- 支持多平台:IE、Chrome、Firefox、edge、Safari
- 支持多语言:Python、C、Java、C#、ruby、js
- 免费小巧,支持分布式测试用例的执行,可以把测试用例分布到不同的测试机器执行,相当于分发机的功能。
自动化工具和自动化框架的区别
在学习selenium的过程中,我们写测试脚本需要使用unittest框架,这个框架提供的类或函数可以实现我们想要实现的测试功能。自动化测试框架一般可以分为两个层次,上层是管理整个自动化测试的开发,执行以及维护,在比较庞大的项目中,它体现重要的作用,它可以管理整个自动测试,包括自动化测试用例执行的次序、测试脚本的维护、以及集中管理测试用例、测试报告和测试任务等。下层主要是测试脚本的开发,充分的使用相关的测试工具,构建测试驱动,并完成测试业务逻辑。
自动化工具本片博客主要说的是selenium,除此之外,还有QTP、Rational Robot 、jmeter、appium、soapui、Loadrunner等等,以后有时间再去学习一下。工具主要的特点就是每个工具都有自己独特的操作界面供用户使用,selenium中的Selenium IDE就是自动化测试工具。
自动化测试适合适用什么项目,适合在什么时机做这种自动化合适?
自动化测试分为UI自动化测试和接口自动化测试。
UI自动化测试:适用于界面比较稳定的项目,前端开发完成之后,并且项目功能稳定。UI界面测试适合进行回归测试以及兼容性测试。
接口自动化测试:适用于后端开发完成,并且项目功能稳定;后端完成之后,就可以进行接口测试。做接口自动化的工具:soupUI、jmeter。
实施自动化测试的前提条件:需求变动不频繁、项目周期长、自动化测试脚本可以重复使用。
自动化适合的项目:产品型项目、机械并频繁的测试(比如兼容性测试)
自动化测试的优势
降低大型系统的由于变更或者多期开发引起的大量的回归测试的人力投入,这可能是自动化测试最主要的任务,特
别是在程序修改比较频繁时,效果是非常明显的,自动化测试前期人力投入较多,但后期进入维护期后,可节省大
量人力,而手工测试后期需要增加大量人力用于回归测试。
- 减少重复测试的时间,实现快速回归测试
- 创建优良可靠的测试过程,减少人为错误
- 可以运行更多更繁琐的测试
- 可以执行一些手工测试困难或不可能进行的测试
- 更好的利用资源
- 测试具有一致性和重复性
- 测试脚本的重用性
Selenium主要有三个版本,分别是Selenium1.0,Selenium2.0,Selenium3.0
Selenium1.0:包括selenium IDE、selenium RC、selenium Grid(支持分布式)。Selenium1.0核心是selenium RC,所以Selenium1.0又称为Selenium RC,它是在浏览器中运用JavaScript应用,即用JavaScript代码获取页面上的任何元素并执行各种操作
Selenium2.0:核心是WebDriver,Selenium+WebDriver
WebDriver的原理:
(1)启动web浏览器,后台会同时启动基于Webdriver Wire协议的Web服务器作为selenium的远程服务器,并将其与浏览器绑定。绑定完成之后,服务器就开始监听客户端的操作请求。
(2)执行测试时,测试用例会作为客户端,将需要执行的页面操作请求以HTTP请求的方式发送给远程服务器。该HTTP请求的正文以Webdriver Wire协议规定的JSON格式来描述需要浏览器执行的具体操作。
(3)远程服务器接收到请求后,会对请求进行解析,并将解析结果发送给Webdriver,由Webdriver实际执行浏览器的操作。
(4)Webdriver可以看作是直接操作浏览器的原生组件,所以搭建测试环境时,通常需要先下载浏览器对应的WebDriver。
业界有一个形象的比喻来理解:乘客和出租车的例子。乘客就是客户端编写的测试脚本,司机就是我们的WedDriver,而出租车就是浏览器。

Selenium3.0:增加了edge 、Safari的原生驱动
学习Selenium主要就是学习WebDriver常用的API
注意:关闭窗口主要有两种方法,分别是close和quit。close是关闭当前浏览器窗口,quit不仅关闭窗口,还会彻底的退出webdriver,释放driver server之间的连接,所以quit的关闭比close更彻底,它会更好的释放资源。
元素的定位
对页面元素进行定位是自动化测试的核心,我们要想操作一个对象,首先应该识别这个对象。在一个页面中,每个对象属性是唯一的我们需要用一系列的方式去定位我们要操作的对象。WebDriver提供了以下几种方法定位元素:
- id
- name
- class name
- link text
- partial link text
- tag name
- xpath
- css selector
下面我将对每种定位方法进行举例。
智能等待
前面说过等待可以引入time包,从而在脚本中自由的添加休眠时间 。但是有时候我们不想等待一个固定的时间,于是可以通过implicitly_wait()方法方便的实现智能等待,它在一个时间范围内智能等待。
selenium.webdriver.remote.webdriver.implicitly_wait(time_to_wait)隐式等待一个元素被发现或一个命令完成,这个方法每次会话只需要调用一次time_to_wait
具体用法:
打印信息
使用print打印title和URL
浏览器的最大化
调用启动的浏览器不是全屏的,这样虽然不影响脚本的执行,但有时会影响我们观看脚本执行的变化。使用maximize_window()
设置浏览器的宽高
最大化不够灵活,所以我们可以随意的设置浏览页面的宽高,使用set_window_size(宽,高)
浏览器的前进、后退
我们也可以实现浏览器的前进和后退
控制浏览器滚动条
键盘键用法
键盘组合键用法
实现Ctrl+a,Ctrl+x
操作鼠标需要使用到ActionChains类
- context_click()右击
- double_click()双击
- drag_and_drop()拖动
- move_to_element()移动
定位一组元素
前面我们定位元素时,只定位了某一个特定的对象,但有时我们需要定位一组对象,这就需要使用find_elements方法

- switch_to_frame()多层框架定位
- switch_to_window() 多窗口定位
switch_to_frame()的功能是把当前定位的主体切换到frame里,即frame中实际上嵌入了另一个页面,而webdriver每次只能在一个页面识别,因此才需要用switch_to_frame方法去获取frame中嵌入的页面,对那个页面里的元素进行定位。
switch_to _default_content:从frame中嵌入的页面跳出,跳回到最外面的原始页面中。

多层窗口定位:switch_to_window用法与switch_to_frame相同,如:driver.switch_to_window("windowname")

对于这种定位的思路是:先点击显示出1个下拉菜单,然后再定位该下拉菜单所在的ul,再定位这个ul下的某个具体的link,如果要定位第一个下拉菜单中的Action选项:
对于下拉框里的内容我们需要两次定位,先定位到下拉框,再定位到下拉框内的选项

- text返回alert、confirm、prompt中的文字信息
- accept点击确认按钮
- dismiss点击取消按钮



更多的时候我们在实际应用中碰到的并不是简单的警告框,而是提供更多功能的会话框


上传文件过程一般要打开一个本地窗口,从窗口选择本地文件添加。所以selenium webdriver实现的方法是:只要定位上传按钮,通过send_keys添加本地文件路径就可以了,绝对路径和相对路径都可以,关键是上传的文件存在。
unittest是Python的单元测试,它提供了创建测试用例、测试套件以及批量执行的方案。
作为单元测试的框架,unittest也可以对程序最小模块的一种敏捷化的测试。在自动化测试中,我们虽然不需要做白盒测试,但是必须知道所使用语言的单元测试框架。利用单元测试框架,创建一个类,该类继承了unittest的TestCase,这样可以把每个case看成是一个最小的单元,有测试容器组织起来,到时候直接执行,同时引入测试报告。
unittest各组件的关系如图:

- Test Fixture:测试固件,初始化和清理测试环境,比如创建临时的数据库、文件和目录等,其中setUp和tearDown是最常用的
- TestCase:单元测试用例,是编写单元测试用例常用的类
- TestSuite:单元测试用例的集合,TestSuite也是常用的类
- TestRunner:执行单元测试
- TestReport:生成测试报告
这里我们简单的创建一个测试用例:
可以增加verbosity参数,例如unittest.main(verbosity=2)。在主函数中,直接调用main() ,在main中加入verbosity=2 ,这样测试的结果就会显示的更加详细。这里的verbosity 是一个选项, 表示测试结果的信息复杂度,有三个值:
- 0 ( 静默模式): 你只能获得总的测试用例数和总的结果比如总共100个,失败20 成功80。
- 1 ( 默认模式): 非常类似静默模式只是在每个成功的用例前面有个“ . ” 每个失败的用例前面有个“F”。
- 2 ( 详细模式): 测试结果会显示每个测试用例的所有相关的信息。
构建测试套件
完整的单元测试需要执行很多个测试用例,开发人员通常需要编写多个测试用例才能对某一软件的功能进行比较完整的测试,这些相关的测试用例称为一个测试用例集,在unittest中是用TestSuite类表示的。
如果我们编写了testbaidu1.py和testbaidu2.py两个文件,那我们怎么同时执行这两个文件呢?
这里就需要构建测试套件,构建测试套件有三种方法,不同的情景下用不同的方法:
- 直接加入测试方法:addTest()
- makeSuit()/TestLoader()
- discover()
addTest()的应用
当有多个或几百个测试用例的时候,就需要一个测试容器(测试套件),把测试用例放在容器中进行执行,unittest模块中提供了addSuite类来生成测试套件,使用该类的构造函数可以生成一个测试套件的实例,该类提供了addTest把每个测试用例加入到测试套件中。
将testbaidu1.py,testbaidu2.py,runall.py放在同一级目录下,runall.py文件如下:
上述做法有两个不方便的地方,阻碍脚本的快速执行,必须每次修改runall.py:
1)需要导入所有的py文件,比如import testbaidu1,每新增一个需要导入一个
2)addTest需要增加所有的testcase,如果一个py文件中有10个case,就需要增加10次
于是就引入了makeSuit()/TestLoader()
makeSuite()和TestLoader()
修改runall.py
discover()的应用
discover 是通过递归的方式到其子目录中从指定的目录开始, 找到所有测试模块并返回一个包含它们对象的TestSuite ,然后进行加载与模式匹配唯一的测试文件,discover 参数分别为discover(dir,pattern,top_level_dir=None)
unittest 框架默认加载测试用例的顺序是根据ASCII 码的顺序,数字与字母的顺序为: 0~9,A~Z,a~z 。所以, TestAdd 类会优先于TestBdd 类被发现, test_aaa() 方法会优先于test_ccc() 被执行。对于测试目录与测试文件来说, unittest 框架同样是按照这个规则来加载测试例。
如果想忽略某个用例的执行,可在方法前加@unittest.skip("skipping")
自动化测试中,对于每个单独的case来说,一个case执行结果中,必然会有期望结果与实际结果,来判断该case是通过还是失败。在unittest的库中提供了大量实用方法来检查预期值与实际值来验证case的结果。一般来说,检查条件大体分为等价性、逻辑比较以及其他,如果给定的断言通过,测试会继续执行到下一行的代码,如果断言失败,对应的case测试会立即停止或者生成错误信息(一般可以打印错误信息即可),但不要影响其他的case执行。
unittest的单元测试提供了标准的XUnit断言方法。下面是一些常见的断言:
如前面的例子中:self.assertEqual(u"hao123_上网从这里开始", driver.title)
执行完脚本之后,还需要看到HTML报告,可以通过HTMLTestRunner.py生成测试报告。因为我本机安装的是Python2.7,所以需要下载HTMLTestRunner.py文件,下载地址:http://tungwaiyip.info/software/HTMLTestRunner.html。下载后将其放在testcase目录下或放入安装路径...Python2.7Lib目录下。
将上面的runall.py改成:
测试报告用浏览器打开如图所示:

用例不可能每次都运行成功,也有运行不成功的时候,如果可以捕捉错误,这样就能更方便我们定位错误,因此unittest中有一个函数get_screenshot_as_file可以实现错误截图功能。
脚本实现实例:
如下就是捕捉到的错误截图:

如果需要多次执行一个案例,比如百度搜索,分别输入中文、英文、数字,或者同类型的多个数据,这时我们就想实现一次运行多个测试用例、unittest没有自带数据驱动功能,所以如果使用unittest,同时又要使用数据驱动,那么就可以使用ddt来完成。
需要安装ddt,可以在控制台输入如下命令:
pip install ddt
python setup.py install
ddt的使用方法
dd.ddt
装饰类,也就是继承自TestCase的类。
ddt.data:
装饰测试方法。参数是一系列的值。
ddt.file_data:
装饰测试方法。参数是文件名。文件可以是json 或者 yaml类型。
注意,如果文件以”.yml”或者”.yaml”结尾,ddt会作为yaml类型处理,其他所有文件都会作为json文件处理。
如果文件中是列表,每个列表的值会作为测试用例参数,同时作为测试用例方法名后缀显示。
如果文件中是字典,字典的key会作为测试用例方法的后缀显示,字典的值会作为测试用例参数。
ddt.unpack:
传递的是复杂的数据结构时使用。比如使用元组或者列表,添加unpack之后,ddt会自动把元组或者列表对应到多个参数上。字典也可以这样处理。
实现一个Testddt类,测试ddt.data
test_baidu_data.csv:
测试ddt.file_data
test_baidu_data.json:
版权声明:
本文来源网络,所有图片文章版权属于原作者,如有侵权,联系删除。
本文网址:https://www.mushiming.com/mjsbk/7776.html