1.什么是Selenium?
答案:Selenium是一个开源的web自动化测试框架,主要是基于web uI的自动化测试。现在的版本,逐步增加了对移动端的自动化测试。Selenium支持多种语言进行开发自动化测试脚本,有Java,python,C#,Javascript等等。Selenium支持跨浏览器平台测试。
2.Selenium是否支持用例的执行的引擎?
答案:引擎好比就是一个发动机。Selenium是没有关于测试用例和测试套件管理和执行的模块。我们需要借助第三方单元测试框架来实现用例管理和用例的执行。例如Java中有Junit或者testNG,Python中有unittest单元测试框架。
3.Selenium有什么限制或者缺陷?
答案:除了基于web的软件和mobile的程序,selenium不支持桌面软件自动化测试。软件测试报告,和用例管理只能依赖第三方插件,例如Junit/TestNG和unittest。由于它是免费的软件,所以没有供应商去提供支持和服务,有问题,只能求助selenium社区。还有一个就是,selenium入门门槛可能有点高,需要具备一定编程语言基础的才能玩转
4.如何提高selenium脚本的执行速度?
答案:- Selenium脚本的执行速度受多方面因素的影响,如网速,操作步骤的繁琐程度,页面加载的速度,以及我们在脚本中设置的等待时间,运行脚本的线程数等。所以不能单方面追求运行速度的,要确保稳定性,能稳定地实现回归测试才是关键。
我们可以从以下几个方面来提高速度:
一,减少操作步骤,如经过三四步才能打开我们要测试的页面的话,我们就可以直接通过网址来打开,减少不必要的操作。
二,中断页面加载,如果页面加载的内容过多,我们可以查看一下加载慢的原因,如果加载的内容不影响我们测试,就设置超时时间,中断页面加载。
三,在设置等待时间的时候,可以sleep固定的时间,也可以检测某个元素出现后中断等待也可以提高速度。
四,配置testNG实现多线程。在编写测试用例的时候,一定要实现松耦合,然后在服务器允许的情况下,尽量设置多线程运行,提高执行速度。
5.你的自动化用例的执行策略是什么?
答案: 自动化测试用例的执行策略是要看自动化测试的目的,通常有如下几种策略:
一,自动化测试用例是用来监控的,在此目的下,我们就把自动化测试用例设置成定时执行的,如果每五分钟或是一个小时执行一次,在jenkins上创建一个定时任务即可。
二,必须回归的用例。有些儿测试用例,如BVT测试用例,我们在公司产品任何变动上线之前都需要回归执行。那我们就把测试用例设置成触发式执行,在jenkins上将我们的自动化测试任务绑定到开发的build任务上。当开发人员在仿真环境上部代码的时候,我们的自动化测试用例就会被触发执行。
三,不需要经常执行的测试用例。像全量测试用例,我们没有必要一直回归执行,必竟还是有时间消耗的,有些非主要业务线也不需要时时回归。这类测试用例我们就采用人工执行,在jenkins创建一个任务,需要执行的时候人工去构建即可。
6.什么是持续集成?
答案:- 持续集成源于极限编程(XP),是一种软件实践,软件开发过程中集成步骤是一个漫长并且无法预测的过程。集成过程中可能会爆发大量的问题,因此集成过程需要尽可能小而多,实际上持续集成讲的是不断的去做软件的集成工作。持续集成,最简单的形式是包括一个监控版本控制(SVN等等)变化的工具。当变化被发觉时,这个工具可以自动的编译并测试你的应用。
7.用例在运行过程中经常会出现不稳定的情况,也就是说这次可以通过,下次就没办法通过了,如何去提升用例的稳定性?
答案:time.sleep( )- driver.implicitly_wait(30)- 多用 try 捕捉,处理异常-此时我们要分析出不稳定的原因,然后有针对性的去解决问题。
主要有以下几个方面 :
一,网速问题:有的时候网页加载的比较慢,在程序执行的时候要操作的元素没有显示出来。这种情况比较常见,运行一次网速好的时候通过了,再运行一次,页面没有打开,就不通过了。为了提高稳定性,我们只能牺牲运行时间了,在经常检测失败的元素前加上等待时间,等要操作的元素出现之后再执行下面的操作。
二,Selelnium的原因:Selenium1.0和2.0还是有区别的,有些儿函数在2.0下运行确实有时而有效,时面无效。如果mouseover()函数,就是这种情况, 我们需要避免使用这类的函数。
三,多线程的时候,测试用例间相互影响。虽然多线程的时候运行速度比较快,但是如果用例之间的耦合性没有设计好,也会影响的,如果用例A先于用例B执行的时候,就会影响到用例B;反之则没有问题。这种情况,如果你的自动化测试工程打算多线程的时候,提前就要把测试用例测试的耦合度比较松,尽量没有任何关系,因为多线程的执行顺序是不受控制的。
8.如何去定位页面上动态加载的元素?
答案:触发动态加载元素的事件,直至动态元素出现,进行定位
9.1:RC原理
答案:在Selenium1.0中,是通过Selenium RC服务器作为代理服务器去访问应用从而达到测试的目的。
Selenium RC分为三个部分,Launcher、HttpProxy、Core。
Launcher用于启动浏览器,把Selenium Core加载到浏览器中,并且把浏览器的代理设置为Selenium Server的Http Proxy。
Core是一堆JavaScript的集合,所以本质相当于运行这些JavaScript函数来实现对Html页面的操作。——这也是为什么可以运行在几乎所有主流的浏览器上。
然而直接运行JavaScript会有极大的安全漏洞,所以会受到“同源限制”,在这个基础上,Selenium2.0引入了WebDriver。
9.2Web Driver原理
答案:webDriver是按照client/server模式设计的。client是我们的测试脚本,发送请求;server就是打开的浏览器,用来接收client的请求并作出响应。
具体的工作流程:
webDriver打开浏览器并绑定到指定端口。启动的浏览器作为远程服务器remote server
client通过CommandExecuter发送http请求给远程服务器的侦听端口(the wire protocal)
远程服务器根据原生的浏览器组件来转化为浏览器的本地(native)调用
9.3:web Driver用到的协议:
答案:打开浏览器时:HTTP协议
client端发送http请求到远程服务器的侦听端口:the wire protocol
其中:
有线协议:指的是从点到点获取数据的方式,是应用层的协议。
HTTP协议:是用于从服务器传输超文本标记语言HTML到客户端的通信协议。是一个应用层协议,由请求/响应构成,是一个标准的客户/服务器模式。是一个无状态的协议。(无状态:对事务没有记忆能力,不会保存这次传输的信息——节约内存)
10.Selenium用JavaScript去操作页面元素会碰到什么问题?Selenium是如何解决这个问题的? 、
答案:然而直接在浏览器中运行JavaScript会有很大的安全漏洞,所以就会受到“同源策略”的限制。也就是,当你去要运行一个脚本的时候,会进行同源检查,只有和被操控网页同源的脚本才能被运行。
Selenium1.0是通过采用代理模式来解决这个问题的。
首先测试脚本向Selenium Server发出Http请求建立,那么Selenium Server通过Launcher来启动服务器,将Core加载到浏览器页面中,并将浏览器代理设置为Http Proxy。
其次,测试脚本发送Http请求,Selenium Server对这个Http进行解析,然后通过代理服务器发送JS命令通知Core执行操作浏览器的动作,Core接受到指令后,执行操作。
Selenium Server得到浏览器的Http的请求后,重组请求,获取对应的页面。
最后代理服务器将这个页面返回给浏览器。
在这个基础上,Selenium2.0是通过webDriver来时先跨平台的。WebDriver是针对各个浏览器来开发,是一个远程控制界面,提供了一组接口来发现和操作Web文档中的DOM元素并控制用户代理的行为。
11.如何设计Selenium的自动化测试脚本?
答案:
1. 自动化测试的内容?
2. 自动化测试用例设计的原则
3. 使用的框架/设计模式
12.控件查找方式有几种?
答案:
(1).通过id查询 By.id(ID)
(2).通过name查询 By.name(Name)
(3).通过class查询 By.className(Class)
(4).通过Link查询 By.linkText(LinkText)
(5).通过PartialLinkText查询 By.partialLinkText(PartialLinkText)
(6).通过xpath查询 By.xpath(Xpath)
(7).通过tag查询 By.tagName(Tag)
(8).通过css查询 By.cssSelector(Css)
selenium提供switch_to_alert方法:捕获弹出对话框(可以定位alert、confirm、prompt对话框)
switch_to_alert() --定位弹出对话框
text() --获取对话框文本值
accept() --相当于点击“确认”
dismiss() --相当于点击“取消”
send_keys() --输入值(alert和confirm没有输入对话框,所以就不用能用了,只能使用在prompt里)
13.什么是Selenium Server,它与Selenium Hub有什么不同?
答案:Selenium Server是使用单个服务器作为测试节点的一个独立的应用程序。 Selenium hub代理一个或多个Selenium的节点实例。一个hub 和多个node被称为Selenium grid。运行SeleniumServer与在同一主机上用一个hub和单个节点创建de Selenium grid类似。
14.你如何从Selenium连接到数据库?
答案:Selenium是一个Web UI自动化工具。它不提供任何API来建立数据库连接。这取决于你使用Selenium进行自动化的编程语言。在下面的例子中,我们假设正在使用Java。
一个Connection对象表示与数据库的连接。当我们使用连接方法连接到一个数据库时,我们创建了一个连接对象,它代表了与数据库的连接。单个数据库可能有一个连接或多个连接,还可能有多个连接到不同的数据库上。
我们可以使用Connection对象来做以下事情:
创建用于执行SQL语句的Statement,PreparedStatement和CallableStatement对象。
可以帮助我们提交或回滚一个JDBC事务。
如果你想知道连接到的数据库或数据源信息,Connection对象通过使用DatabaseMetaData就可以收集有关数据库或数据源的信息。
可以帮助我们关闭数据源。Connection.isClosed() 方法只有在调用了Connection.close()时才返回true 。此方法用于关闭所有连接。
首先我们需要通过使用DriverManager.getConnection()方法,建立与数据库的连接。这个方法接受一个包含URL的字符串。DriverManager类尝试查找可以连接到由字符串URL表示的数据库的驱动程序。每当调用getConnection()方法时,DriverManager类都会检查可以连接到URL中指定的数据库的所有已注册的Driver类的列表。
句法:
String url = “jdbc: odbc: makeConnection”;
Connection con = DriverManager.getConnection(url, “userID”, “password”);
15.什么是Selenium的CSS定位器策略?用例子来解释。
答案:CSS位置策略可以与Selenium一起使用来定位元素,它使用CSS定位方法,其中 -
绝对路径用 - (空格符号)
相对路径用 - >表示
ID,类,名称也可以用于XPath:
css=input[name=’q’]
css=input[id=’lst-ib’] or input#lst-ib
css=input[class=’lst’] or input.lst
如果id / name / class只有一部分是常量:
css=input[id*=’lst-ib’)]
使用内部文本的元素位置策略:
css = a:contains(‘log out’)
发起请求:driver.get(url)
获取请求网页的标题:driver.title()
获取某元素ID中的内容:find_element_by_id(‘id名称’)
获取某元素ID中的所有内容:find_elements_by_id(‘id名称’)
获取某xpath中的内容:find_element_by_xpath(xpath)
获取某xpath中的内容:find_elements_by_xpath(xpath)
根据准确文字获取定位:find_element_by_link_text(link_text)
根据准确文字获取定位:find_elements_by_link_text(link_text)
根据模糊文字获取定位:find_element_by_partial_link_text(self, link_text)
根据模糊文字获取定位:find_elements_by_partial_link_text(self, link_text)
通过标签名进行定位:find_element_by_tag_name(name)
通过标签名进行定位:find_elements_by_tag_name(name)
通过class标签查找:find_element_by_class_name(name)
通过class标签查找:find_elements_by_class_name(name)
find_element_by_css_selector(self, css_selector)
find_elements_by_css_selector(self, css_selector)
输入内容:send_keys(*value)
判断某个元素是否存在:is_displayed()
同步执行JavaScript脚本:execute_script(self, script, *args)
xecute_async_script(self, script, *args)
获取当前driver的url:current_url
获取当前driver的html:page_source
关闭当前窗口,或最后打开的窗口:close()
关闭所有窗口:quit()
获取当前窗口:current_window_handle
获取所有窗口:window_handles
最大化窗口:maximize_window
切换窗口:switch_to()
切换到指定窗口:switch_to_window(self, window_name)
switch_to_active_element(self)
switch_to_frame(self, frame_reference)
switch_to_frame(self, frame_reference)
switch_to_default_content(self)
switch_to_alert(self)
返回上一页面: back(self)
返回上一页面:forward(self)
刷新页面:refresh(self)
一种情况就是,当你从一个父页面跳转到子页面进行操作,操作完之后没有“返回”之类的按钮或链接,重新进入父页面又很麻烦,back()可以帮你。forward()与此类似,相对没有back()那么常用
得到cookies信息:get_cookies()
得到指定的cookie信息:get_cookie(self, name)
删除指定的cookie信息:delete_cookie(self, name)
删除所有的cookie信息:delete_all_cookies(self)
添加cookie信息,实现自动登录:add_cookie(self, cookie_dict)
等待页面加载时间:implicitly_wait(self, time_to_wait)
设置等待超时时间:set_script_timeout(self, time_to_wait)
设置等待超时时间:set_page_load_timeout(self, time_to_wait)
根据元素查找:find_element(‘元素类型’,‘元素值’)
根据元素查找:find_elements(‘元素类型’,‘元素值’)
测试脚本分布到哪台服务器或设备进行测试:desired_capabilities(self)
截图:get_screenshot_as_file(self, filename)
save_screenshot(self, filename)
这个是获取屏幕截图,保存的是二进制数据:get_screenshot_as_png(self)
获取屏幕截图,保存的是base64的编码格式,在HTML界面输出截图的时候,会用到:get_screenshot_as_base64(self)
设置窗口的大小:set_window_size(self, width, height, windowHandle='current')
得到窗口的大小:get_window_size(self, windowHandle='current')
设置窗口的打开的坐标:set_window_position(self, x, y, windowHandle='current')
得到窗口当前的坐标:get_window_position(self, windowHandle='current')
设置窗口打开的样式:get_window_rect(self)
set_window_rect(self, x=None, y=None, width=None, height=None)
file_detector(self, detector)
orientation(self)
orientation(self, value)
application_cache(self)
获取当前driver的日志类型:log_types(self)
得到当前driver的日志:get_log(self, log_type)
execute_async_script():
current_url:获取当前请求的URL
page_source
close
Quit()
current_window_handle
window_handles
maximize_window
switch_to_window:切换窗口
switch_to_active_element
switch_to_alert:
Back
Forward
Refresh:刷新
get_cookies:获取当前driver的所有cookie
get_cookie:得到所有cookie
delete_cookie:删除cookie
delete_all_cookies:删除所有cookie
implicitly_wait:等待加载时间
set_script_timeout:设置间隔时间
set_page_load_timeout:页面加载完成时间
find_element:查找元素
find_elements:
desired_capabilities:
get_screenshot_as_file(self, filename):截图功能
get_screenshot_as_png:
get_screenshot_as_base64:
set_window_size(self, width, height, windowHandle='current'):模仿人为拖动窗口的大小
get_window_size(self, windowHandle='current'):得到窗口的大小
set_window_position(self, x, y, windowHandle='current')
get_window_position(self, windowHandle='current')
get_window_rect
set_window_rect(self, x=None, y=None, width=None, height=None)
get_log:获取drive日志
获取alert弹框中的文本
alert_text = driver.switch_to.alert
sleep(1)
text = alert_text.text
print(text)
Selenium模仿真实用户 测试直接在浏览器中运行,就像真实用户所做的一样,代替部分人工测试。
Selenium IDE、Selenium RC、Selenium WebDriver、Selenium Grid
Selenium IDE:
支持通过界面进行录制,并将录制内容翻译成自动化测试脚本(使用selenium的一系列函数)。对没有编程经验的人来说,可以不需要手写具体脚本,
Selenium RC:
SeleniumRC分为ClientLibraries和SeleniumServer。
Client Library提供每个编程语言和Selenium Server的接口,负责自动化脚本部分,用来发送命令给selenium server,同时接收测试结果
SeleniumServer:控制浏览器,解释和执行测试代码,同时作为HTTP代理,用拦截和处理浏览器和服务器之间的HTTP请求
SeleniumServer包含Launcher,Http Proxy和Core
Launcher 用于启动浏览器,把Selenium Core加载到浏览器页面当中,并把浏览器的代理设置为SeleniumServer 的 HttpProxy。
Selenium Grid:
Selenium Grid也是Selenium Suite的一个重要组件,它允许在不同的机器上并行运行不同浏览器的测试。 简单来说,可以在运行不同浏览器和操作系统的不同机器上同时运行测试。
WebDriver:
Selenium RC使用的是JavaScript注入技术与浏览器打交道、WebDriver的概念之后,它提供了完全另外的一种方式与浏览器交互。那就是利用浏览器原生的API,封装成一套更加面向对象的SeleniumWebDriver API,直接操作浏览器页面里的元素,甚至操作浏览器本身(截屏,窗口大小,启动,关闭,安装插件,配置证书之类的)。由于使用的是浏览器原生的API,速度大大提高,而且调用的稳定性交给了浏览器厂商本身,显然是更加科学,这就直接导致了Selenium WebDriver 要分浏览器厂商不同,而提供不同的webdriver
他完全就是一套类库,不依赖于任何测试框架,除了必要的浏览器驱动,
常见的8种元素定位方式:
常见的功能方法:
介于代码和浏览器执行速度的差异,抛出二个等待方式:
模拟人的行为方法:
包括:鼠标操作、键盘操作、下拉框、警告框、滚动条、frame表单切换、多窗口切换、截屏等等
好处:
1、Selenium模仿真实用户 测试直接在浏览器中运行,就像真实用户所做的一样。
2、节省人力,不用做大量重复性的工作,
1、 节省时间、随时回测,
2、 提高置信度,测试时机器执行的,人工长时间的点击测试,有疏忽的地方,
当然也有缺点:
1、 脚本维护成本高,尤其是版本变动比较大,对于测试用例集(测试项目)风险较大
2、 不易发现新的bug,在人工测试中,对于页面的结构的位置,图片样式,按钮样式、整体界面风格无法把控
平衡点:
自动化加人工测试,主干路和功能自动化,保证功能的合理、可用性;人工把控结构样式和风格
Python+selenium+unitTest+pycharm
1. TestCase:(翻译:测试用例)一个TestCase就是一条测试用例;
2. TestSuite:(翻译:测试套件)多条测试用例集合在一起,就是一个TestSuite
3. TextTestRunner:(翻译:测试执行)是用来执行测试用例套件
多个测试点只用执行一次(只打开一个浏览器)
@classmethod
def setUpClass(cls):
def tearDownClass(cls):
expected_conditions中的16中方法配合assert进行断言
title_is: 判断当前页面的title是否完全等于(==)预期字符串,返回布尔值
title_contains : 判断当前页面的title是否包含预期字符串,返回布尔值
presence_of_element_located : 判断某个元素是否被加到了dom树里,并不代表该元素一定可见
visibility_of_element_located : 判断某个元素是否可见. 可见代表元素非隐藏,并且元素的宽和高都不等于0
visibility_of : 跟上面的方法做一样的事情,只是上面的方法要传入locator,这个方法直接传定位到的element就好了
presence_of_all_elements_located : 判断是否至少有1个元素存在于dom树中。举个例子,如果页面上有n个元素的class都是'column-md-3',那么只要有1个元素存在,这个方法就返回True
text_to_be_present_in_element : 判断某个元素中的text是否 包含 了预期的字符串
text_to_be_present_in_element_value : 判断某个元素中的value属性是否 包含 了预期的字符串
frame_to_be_available_and_switch_to_it : 判断该frame是否可以switch进去,如果可以的话,返回True并且switch进去,否则返回False
invisibility_of_element_located : 判断某个元素中是否不存在于dom树或不可见
element_to_be_clickable : 判断某个元素中是否可见并且是enable的,这样的话才叫clickable
staleness_of : 等某个元素从dom树中移除,注意,这个方法也是返回True或False
element_to_be_selected : 判断某个元素是否被选中了,一般用在select下拉列表
element_selection_state_to_be : 判断某个元素的选中状态是否符合预期
element_located_selection_state_to_be : 跟上面的方法作用一样,只是上面的方法传入定位到的element,而这个方法传入locator
alert_is_present : 判断页面上是否存在alert