单元测试:是指对软件代码中最小单元的测试,比如函数,模块,是一种白盒测试
单元测试框架:单元测试框架是一种模板、规范,能够有条理地组织我们的自动化测试用例代码,提供断言,能指定测试用例的执行顺序,将特定的测试用例集合在一起去执行,也能生成测试报告.unittest和pytest是常见的单元测试框架。
单元测试框架和自动化测试框架的区别:关键字驱动,数据驱动,单元测试框架是自动化框架的组成部分
一.pytest的特点
- 简单灵活,容易上手,文档丰富
- 支持参数化,可以细粒度地控制要测试的测试用例
- 能支持简单的单元测试和复杂的功能测试, 还可以用来做selenium/appium等自动化测试、接口测试(pytest+requests)
- pytest具有很多第三方插件,并且可以自定义扩展,比较好用的如pytest-selenium(集成selenium)、pytest-html(完美html测试报告生成)、pytest-rerunfailures(失败case重复执行)、pytest-xdist(多CPU分发)等.
二. pytest 安装
1 pip install –U pytest # 参数-U指安装最新版本
2 pytest —version # 查看版本信息
三. pytest用例编写规范
测试文件以 test_ 开头(以 _test 结尾也可以)
测试类以 Test 开头,并且不能带有 init 方法
测试函数以 test_ 开头
断言使用 assert
四. 运行结果说明
执行结果中,F代表用例未通过(断言错误),. 用例通过。如果有报错会有详细的错误信息.
五. 常用运行参数说明
pytest 带有很多参数,可以使用 pytest –help 来查看帮助文档,下面介绍几种常用的参数:
无参数:读取路径下所有符合规则的文件,类,方法,函数全部执行
-v:打印详细运行日志信息,一般在调试的时候加上这个参数,终端会打印出每条用例的详细日志
信息,方便定位问题.
-s: 参数带控制台输出结果,当你的代码里面有 print 输出语句,如果想在运行结果中打印 print
输出的代码,在运行的时候可以添加 -s 参数,一般在调试的时候使用.
import pytest def setup_module(): print('作用于整个模块') #在整个模块面前调用一次 def teardown_module(): print('作用于关闭模块')#在整个模块执行完毕后执行 class TestCase1: def test_001(self): print('用例1') class TestCase2: def setup_class(self): print('类的前置条件,打开浏览器,创建数据库连接') def teardown_class(self): print('类的后置条件,作用于关闭模块') def setup(self): print('方法执行前要做的事情,打开浏览器,创建数据库连接,加载网页') def teardown(self): print('方法执行后要做的事情,关闭浏览器') def test_01(self): print('第一条用例') assert 1 == 1 def test_02(self): print('第二条用例') assert '1' == 1 def test_01(self): print('第一条用例') assert 1 == 2 #运行有两种方式,一种是main方法运行,一种是终端里运行 if __name__ == '__main__': pytest.main(['-s','-v','test_demo.py'])
运行结果:


-x:遇到用例失败立即停止运行.
-q:输出更简化的信息,与-v相反.
-k: 运行含有该表达式的用例.
使用方法如下:
pytest -k ‘类名’
pytest -k ‘方法名‘
pytest -k ‘类名 and not 方法名‘ //运行类里所有的方法,不包含某个方法
-m:将运行有 @pytest.mark.[标记名] 这个标记的测试用例:使用方法如下:
pytest –m [标记名]
import pytest class TestCase2: def setup(self): print('方法执行前要做的事情,打开浏览器,创建数据库连接,加载网页') def teardown(self): print('方法执行后要做的事情,关闭浏览器') @pytest.mark.smoke #加上这个装饰器以后整个测试用例只执行这一关 def test_01(self): print('第一条用例') assert 1 == 1 def test_02(self): print('第二条用例') assert '1' == 1 def test_01(self): print('第一条用例') assert 1 == 2 #运行有两种方式,一种是main方法运行,一种是终端里运行 if __name__ == '__main__': pytest.main(['-s','-v','-m','smoke','test_demo.py']) #加上'-m','smoke'
同时要在pytest.ini文件里做一些修改,在pytest.ini文件可以改变一些pytest的原有规则
[pytest] python_files=test_*.py *_test.py #代表Python文件要以test开头或结尾 python_classes = Test* #代表指定类名要以Test开头 python_functions = test_* #代表指定函数名要以test_开头 markers = smoke #标记名
六. 控制用例的执行顺序
pytest order
使用 pytest-order 插件,指定用例的执行顺序只需要在测试用例的方法前面加上装饰,
@pytest.mark.run(order=[num]) 设置order的对应的num值,它就可以按照 num 的大小顺序来
执行
安装:pip install pytest-ordering
被@pytest.mark.last装饰的,永远最后执行
被装饰的用例之间,执行顺序按照order值的大小执行,值越小越先执行
import pytest class TestCase2: def setup(self): print('方法执行前要做的事情,打开浏览器,创建数据库连接,加载网页') def teardown(self): print('方法执行后要做的事情,关闭浏览器') @pytest.mark.run(order=3) def test_01(self): print('第一条用例') assert 1 == 1 @pytest.mark.run(order=2) def test_02(self): print('第二条用例') assert '1' == 1 @pytest.mark.run(order=1) def test_01(self): print('第一条用例') assert 1 == 2 #运行有两种方式,一种是main方法运行,一种是终端里运行 if __name__ == '__main__': pytest.main(['-s','-v',,'test_demo.py']) #执行顺序为test_3,test_2,test_1
七.跳过指定测试用例
@pytest.mark.skipif()
@pytest.mark.skip()
import pytest class TestCase2: def setup(self): print('方法执行前要做的事情,打开浏览器,创建数据库连接,加载网页') def teardown(self): print('方法执行后要做的事情,关闭浏览器') @pytest.mark.skip(reason='跳过没有理由') #这条测试用例将不会被执行 def test_01(self): print('第一条用例') assert 1 == 1 @pytest.mark.skipif(num>3,reason='跳过没有理由') #这条测试用例将不会被执行 def test_02(self): print('第二条用例') assert '1' == 1 @pytest.mark.run(order=1) def test_01(self): print('第一条用例') assert 1 == 2 #运行有两种方式,一种是main方法运行,一种是终端里运行 if __name__ == '__main__': pytest.main(['-s','-v',,'test_demo.py']) #执行顺序为test_3,test_2,test_1
八.测试报告
如果你对测试报告要求没那么高,你可以使用 pytest-html 插件,基本覆盖了测试报告的常规内容。
但是如果你想查看清晰的测试过程、多维度的测试报告、自定义一些输出,以及与用例和缺陷系统集成等,那allure-pytest将是你的”不二人选”。
1.安装allure-pytest pip install allure-pytest
2.allure工具的官方下载地址:Releases · allure-framework/allure2 · GitHub
3.解压软件包(建议直接放到Python文件夹下),然后添加bin目录到环境变量中,最后使用 allure –version 验证是否安装成功。
4.
import pytest import os if __name__ == '__main__': #测试数据生成在当前目录下的allure-results pytest.main(['-s','./test_case/test_demo.py','--alluredir','./allure-results']) #根据测试数据在当前目录下生成测试报告reports os.system('allure generate ./allure-results -o ./reports')
运行生成以下目录
九. 多线程并发与分布式执行
import pytest import os if __name__ == '__main__': #并发2个线程执行测试用例 pytest.main(['-s','-n','2','./test_case/test_demo.py','--alluredir','./allure-results']) #pytest.main(['-s','-n','auto','./test_case/test_demo.py','--alluredir','./allure-results']) os.system('allure generate ./allure-results -o ./reports')
发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/225352.html原文链接:https://javaforall.net
