Pytest
对于单元测试框架的核心功能:
-收集用例
-指定用例函数的定义规则(比如unittest的用例,模块和收集用例的文件夹是以test开头)
-自动执行用例
-前置和后置的夹具
-断言
-生成测试报告
pytest用例编写规则比较灵活:
需要更换单元测试框架
用例函数
测试用例函数还是要以test_开头
1,直接定义函数,不需要测试类
#方法1 def test_pytest_1(): actual = 1 expected = 2 assert actual == expected
2,编写测试类,不继承unittest.TestCase
#方法2 class TestPytest_2: def test_pytest_2(self): pass
3,编写测试类,继承unittest.TestCase,可以直接迁移(兼容)
#方法3 import unittest class TestPytest_3(unittest.TestCase): def test_pytest_3(self): actual = 1 expected = 2 self.assertEqual(actual,expected)断言
直接使用python关键字 assert
assert actual == expected收集用例,自动执行用例
方式1:进入用例目录,代表执行目录下所有test开头用例,命令行输入pytest
开始执行用例
执行结果
方式2:通过python代码
建立run.py文件,里面使用pytest的main方法表示运行当前目录下的test_开头的文件,跟在命令行输入pytest一样
"""pytest 运行项目""" import pytest pytest.main()
生成报告
安装插件 pytest-html
方式1:命令行输入
参数填入测试报告的名称--html=名称.html,默认会在所在目录下生成测试报告,如果下次生成报告的名称相同,则会覆盖原有报告
方式2:通过python代码
建立run.py文件,里面使用pytest的main方法表示运行当前目录下的test_开头的文件并且生成报告
main()方法里填入一个列表的参数,列表里要生成测试报告的路径和名称,可以加上时间戳
"""pytest 运行项目""" import pytest from datetime import datetime #收集并且运行用例 #命令行参数放入main里列表当中 ts = datetime.now().strftime("%Y-%m-%d-%H-%M-%S") pytest.main([f"--html=reports/report-{ts}.html"])
pytest中 测试报告默认生成在当前.py文件的目录下,需要手工指定一个生成的目录,unittest会自动生成reports目录
夹具导入pytest
import pytest
声明夹具函数
@pytest.fixture() def function_fixture(): print("每个用例前执行一次") # setUp yield print("每个用例后执行一次") # tearDown
使用yield
yield上面代表先执行,yield表示运行完上面的 *** 作后要运行函数,yield下面表示运行函数后才运行
在测试用例函数中,把夹具函数当做参数(不加括号)写入
class TestFixture: def test_fixture(self,function_fixture,class_fixture,module_fixture): print("执行函数1") assert 1+ 1 == 2
共享fixtures
1,将所有的夹具全部放到一个固定的模块文件,conftest.py(固定名称)
2,所有导入夹具的 *** 作就可以省略,pytest运行时会自动在conftest.py中查找,路径是项目根目录下
非常灵活的作用域管理
-function级别 每个用例执行一次
#函数级别 @pytest.fixture() def function_fixture(): print("每个用例前执行一次") # setUp yield print("每个用例后执行一次") # tearDown
-class级别 每个类执行一次,需要填入参数scope=”class”
#类级别 @pytest.fixture(scope="class") def class_fixture(): print("每个类前执行一次") # setUp yield print("每个类后执行一次") # tearDown
-module级别 每个模块执行一次,需要填入参数scope=”module”
#模块级别 @pytest.fixture(scope="module") def module_fixture(): print("每个模块前执行一次") # setUp yield print("每个模块后执行一次") # tearDown
在每个测试用例方法的参数中,填入需要使用的夹具的名称
class TestFixture: def test_fixture(self,function_fixture,class_fixture,module_fixture): print("执行函数1") assert 1+ 1 == 2 def test_fixture_2(self, function_fixture, class_fixture,module_fixture): print("执行函数2") assert 1 + 1 == 2 class TestFixture2: def test_fixture(self,function_fixture,class_fixture,module_fixture): print("执行函数3") assert 1+ 1 == 2夹具中定义属性
在夹具函数里定义属性,然后return返回
如果有后置 *** 作的话,在yield后加属性名
待续...
autouse 自动使用夹具
在想要自动使用的夹具函数参数中加入scope=True,就不用在测试函数中填入夹具名称,也能自动使用夹具
Pytest 参数化声明pytest.mark.prarmetrize(),第一个参数填入一个字符串,在下面的方法的参数中填入同名的变量,代表遍历列表中的元素,每次取出其中一个,用这个变量接收
第二个参数填入读取excel结果(列表)
import pytest data = [1,2,3] class TestParams: @pytest.mark.parametrize("case_info",data) def test_params(self,case_info): print(case_info) assert 1+1==2pytest用例筛选
1,提前把标记名注册到pytest
2,通过pytest在测试类/方法上做一个标记
import pytest @pytest.mark.success class TestMark(): @pytest.mark.login def test_mark(self): assert 1+1==2 def test_mark1(self): assert 1+1==3
3,在运行用例时,通过标记执行
收集到8个用例 7个被过滤 一个符合
如果是声明在类上面的话 就表示类下面所有函数都符合
标记组合,支持逻辑运算and or not
只有1用例被筛选出来,2用例符合success标记而不符合login标记
有两个用例符合
pytest参数化和fixture是跟unittest不兼容
实战当中的两种模式
1,使用unittest编写用例,使用unittest ddt和夹具,但是用pytest运行
2,全部使用pytest,使用pytest参数化和pytest夹具,舍弃unittest
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)