自动化测试框架——持续更新中
一、什么是框架 ?
框架是一个应用系统的半成品,开发人员在框架的基础上,根据业务需求开发功能。其对基础代码进行封装并且提供API接口,其他开发者只需要直接调用封装好的API接口即可。
例如:selenium是框架 ,find_element()是接口。
二、什么是自动化框架以及它的作用?
1.自动化框架
为了对一个系统做自动化测试而封装的一个代码框架,只需要去调用这个框架里面的方法就可以实施自动化测试。
2.自动化框架的作用
1.提高测试效率,降低维护成本。
2.增加代码的可重用率。
3.可以直接调用框架的API来实现功能,而不需要关注框架的底层具体使用了哪些技术,提高开发效率。
三、常见单元测试框架以及与自动化测试框架的关系
1.常见单元测试框架
单元测试是自动化测试的核心,指的是针对我们程序的最小单元(方法)进行测试。在自动化测试里,单元测试将会是自动化测试最小的单位,若干个单位组成一个整体,这就是自动化测试。每一种变成语言都有自己的单元测试框架,例如Python的unittest、pytest;java的TestNG、Junit。
2.部分与自动化测试框架关系
- unittest是自动化测试框架的重要的组成部分之一。
- ddt数据驱动是自动化框架的重要的组成部分之一。
- 全局配置文件封装是自动化框架的重要的组成部分之一。
- selenium二次封装是自动化框架的重要的组成部分之一。
- 日志监控是自动化框架的重要的组成部分之一。
- 断言,邮件发送等等同样也是自动化框架的重要的组成部分之一。
这个可以根据代码结构看出来,automation_framework可以理解为整个的自动化框架,下层又分为base、case、common等模块,这些模块其实指的就是上面提到的selenium二次封装、等自动化框架组成部分。
也可以参考下方图片,帮助我们理解
3.什么是POM?
POM是Page Object Model的缩写,中文意思是页面对象模型,POM不是一个框架,是一种解决问题的思想。采用POM的目的,是为了解决前端中UI变化频繁造成自动化维护成本越来越大的问题。
左侧为不采用POM模式,把页面元素和测试用例都写在一个类文件中,如需要更改页面,那么页面元素和测试用例代码两者均需更改,维护成本极高;右侧为采用POM模式,把页面元素和测试用例写在两个类文件中,带来的好处就是假如要修改UI界面,只需要修改元素定位信息,测试用例基本上不用动。
通过以上的讲述,可以明显看到POM带来的好处,我列举以下几点:
- 把UI对象仓库从测试代码中分离出来。
- 每个页面对应一个页面类,页面的元素写在这个页面类中。
- 页面类中主要包含该页面元素定位,以及封装的相关的页面元素操作方法
四.unittest
1.unittest框架主要做了什么
1.测试发现:从多个py文件中收集并且加载测试用例
2.测试执行:将测试用例按照一定的顺序和条件去执行并且生成结果
3.测试判断:通过断言去判断结果是否正确
4.测试报告:统计测试进度,通过率,生成报告。
2.Unittest重要组件
1.TestCase
中文:测试用例,是一个独立的测试单元,也可以把它看成是一条测试用例,它继承于Unittest提供的基类TestCase。
例:
import unittest
class SysLogin(unittest.TestCase):
def test01_tom(self):
print("tom")
def test02_jerry(self):
print("jerry")
步骤:
1.导入unittest包
2.类继承unittest.TestCase类
3.方法以test_开头或者_test结尾
2.TestSuite
中文:测试套件,是一组测试用例的集合,可以是一组Test Suite的集合,也可以是两者混合的集合,通过Test Suite用户可以选择性的执行测试用例,在测试过程的不同阶段,并不是每层都执行全部用例。
单个TestCase
1.创建Testsuite对象:suite = unittest.TestSuite()
2.添加TestCase到Testsuite中:suite.addTest(TestClass("TestMethod"))
3.创建TestRunner对象:runner = unittest.TextTestRunner()
4.运行:runner.run(suite)
一个类下所有的TestCase
1.创建Testsuite对象并加载:suite = unittest.TestSuite(unittest.makeSuite(测试类名称))
2.创建TestRunner对象:runner = unittest.TextTestRunner()
3.运行:runner.run(suite)
目录下的所有的TestCase
1.创建Testsuite对象并加载:suite = unittest.TestLoader().discover("path", "filename")
或suite = unittest.defaultTestLoader.discover("path", "filename")
2.创建TestRunner对象:runner = unittest.TextTestRunner()
3.运行:runner.run(suite)
注意:suite.addTest(SysLogin('test01_tom'))
,类需要导入,或者与其在同一目录下
下图SysLogin类与此文件不在同一目录且没有导入,会报错
3.TestFixture
中文:测试固件或者测试夹具,执行单个或多个测试用例时的准备工作和工作执行结束后的一些相关清理工作
setuUp/tearDown(常用)
在每个用例之前或之后与运行一次。例如:打开浏览器,加载网页/关闭网页。
class TestOperationMenu(unittest.TestCase):
driver = None
def setUp(self):
self.driver = BrowserEngine().open_browser()
def tearDown(self):
self.driver.quit()
def test_operation_menu_case001(self):
......
setUpClass和tearDownClass (常用)
在每个类运行之前或之后运行一次。例如:创建数据库连接,创建日志对象/关闭数据库连接,销毁日志对象。
setUpModule和tearDownModule (不常用)
在每个块之前和之后执行一次。
4.TestLoader
中文:测试加载器
将用例加载到Testsuite中
5.TestRunner
中文:测试运行器,是一个统筹测试执行并生成执行结果的组件,它可以使用图形界面、文件页面或返回一个特殊值标识测试执行的结果。
3.unittest常用运行方式
1.命令行方式
-
执行测试模块:python -m unittest test_modulel test_module2…也可以采用路径的方式python -m unittest tests/test_something.py,如果想用一个高级verbosit的方式执行加上参数-v即可,如 python -m unitest -v test_module。
-
执行测试类:python -m unittest test _modulel.Test Class.
-
执行测试方法:python -m unittest test_modulel.Test Class.test method。
2.使用unittest.main(),以模块的方式运行
unittest.main()会将模块的测试用例收集起来并执行,然而当测试用例增多了以后,这样的执行非常不灵活而且没有效率。
配置pycharm环境
(1)点击下图处倒三角标志,点击edit configurations
(2)下方分为python、pytest
如果选择python初始环境运行,选择python,如果选择命令行,选择pytest
(3)点击+号,选择python,填写路径,点击应用
(4)倒三角处,选择刚配置的环境,点击运行
4.读懂运行结果
- . 成功
- E 错误
- S 跳过
- F 失败
5.用例执行的顺序
方法名的字符串ASCII码排序后的顺序执行。如果想自定义顺序执行,需要使用TestSuite(),它的执行顺序是按照addTest()次序执行的。
五.pytest框架
待更新
六、单元测试框架对比
主要是unittest与pytest的对比
1.用例编写规则
unittest:提供了testcases测试用例、testsuites测试套件、testfixtures测试固件或夹具、testload测试加载器,testrunner测试运行器。必须遵守以下规则:
(1)测试文件必须先导入import unittest。
(2)测试类必须继承unittest.TestCase。
(3)测试方法必须以test开头。
pytest:它是python的第三方测试框架。基于unittest的扩展框架,必须遵守以下规则:
(1)测试文件名必须以test 开头或者是 test结尾。
(2)测试类命令必须以Test开头。
(3)测试方法必须test开头。
2.用例的前置和后置
(1)unittest
setuUp/tearDown
在每个用例之前或之后与运行一次。例如:打开浏览器,加载网页/关闭网页。
setUpClass和tearDownClass
在每个类运行之前或之后运行一次。例如:创建数据库连接,创建日志对象/关闭数据库连接,销毁日志对象。
setUpModule和tearDownModule
在每个块之前和之后执行一次。
(2)pytest
方法级:setup_mothod/teardown_mothod 或setup/teardown
在方法之前和之后,上述两者均可,pytest优先找第一种执行。
函教级:setup_function/teardown funciton
在函数之前和之后
类级:setup_class/teardown_class
模块级 :setup_module/teardown_module
还可以加@pytest.fixture装饰器,其能实现上述功能
3.断言
unites :assertTrue ,assertEqual ,assertln
self.assertEqual(info, '登录失败 : 用户名或者密码错误')
"""
断言时要加上self如果是在类中的话,可以把这个断言看成对象的一个属性
"""
pytest : assert
assert info == '登录失败 : 用户名或者密码错误'
4.报告
unittest : htmiltestrunner
pytest:插件-pytest-HTML,allure
5.失败重跑
unittest:没有
pytest : pytest-rerunfailures插件
6.数据驱动
参考我的另一篇文章:添加链接描述
unitest : ddt
pytest": @pytest.mark.parametrize装饰器
7.用例分类执行
unittest:默认执行所有,也可以通过testsuite来执行部分用例,或者-k参数,后面会详细展开
pytest : @pytest.mark