【Python】测试框架之pytest初识
前提:
安装:pip install pytest
一、pytest_常用运行参数
import pytest class TestClass: def test_01(self): print(1) assert True def test_02(self): print(2) assert 1 == 2 @pytest.mark.taomj def test_03(self): print(3) assert True @pytest.mark.taomj def test_04(self): print(5) assert 1 == 2 if __name__ == '__main__': pytest.main(['demo6_pytest_常用运行参数.py']) # -v 用于显示每个测试函数的执行结果(用于打印显示每条用例的执行情况) # pytest.main(['-v', 'pytest_常用运行参数.py']) # -q 只显示整体测试结果(简化测试整体结果。F:代表测试失败、.:代表测试通过) # pytest.main(['-q', 'pytest_常用运行参数.py']) # -s 用于显示测试函数中print()函数输出(显示测试用例中 print() 中的值) # pytest.main(['-v', '-s', 'pytest_常用运行参数.py']) # -x 在第一个错误或失败的测试中立即退出(第一条用例执行失败,立即退出不在往下执行用例) # pytest.main(['-v', '-x', 'pytest_常用运行参数.py']) # -m 只运行带有装饰器配置的测试用例 # pytest.main(['-v', '-m taomj', 'pytest_常用运行参数.py']) # -k 通过表达式运行指定的测试用例 # pytest.main(['-v', '-k test_02', 'pytest_常用运行参数.py']) # -h 帮助 # pytest.main(['-h'])
二、pytest_跳过测试
import pytest def test_1(): print('不跳过') def test_2(): pytest.skip('函数内跳过') print('函数内跳过') @pytest.mark.skip(reason='函数外跳过,无条件') def test_3(): print('函数外跳过,无条件') @pytest.mark.skipif(condition='1<2', reason='函数外跳过,条件满足') def test_4(): print('函数外跳过,条件满足') @pytest.mark.skipif(condition='1>2', reason='函数外跳过,条件不满足') # 跳过用例 def test_5(): print('函数外跳过,条件不满足') if __name__ == '__main__': pytest.main(['-vs', 'pytest_mark_skip.py'])
三、pytest_失败重跑机制
1、安装:pip install pytest-rerunfailure
2、代码如下:
import pytest def add(a, b): return a + b # reruns:总共执行几次,reruns_delay:每次执行的间隔 @pytest.mark.flaky(reruns=2, reruns_delay=1) def test_rerun(): assert add(1, 2) == 4 if __name__ == '__main__': pytest.main(['-v', 'pytest_mark_flaky.py'])
四、pytest_重复运行
1、安装:pip install pytest-repeat
2、代码如下:
import pytest @pytest.mark.parametrize("user", ["18221124104"]) @pytest.mark.repeat(3) def test_1(user): print(user) assert user == "18221124104" if __name__ == "__main__": pytest.main(["-vs", "pytest_mark_repeat.py"])
五、pytest_运行顺序设置
1、安装:pip install pytest-ordering
2、代码如下:
# 执行顺序:由小到大、由正到负、未标记的在正数后、负数前执行,顺序为:1,2,3,无标记,-3,-2,-1 import pytest class TestClass(object): @pytest.mark.run(order=-1) def test_01(self): print(-1) @pytest.mark.run(order=-3) def test_02(self): print(-3) @pytest.mark.run() def test_03(self): print('') @pytest.mark.run(order=1) def test_04(self): print(1) @pytest.mark.run(order=2) def test_05(self): print(2) if __name__ == '__main__': pytest.main(['-vs', 'pytest_mark_run.py'])
六、pytest_参数化
import time import pytest # 单参数单值 @pytest.mark.parametrize("user", ["18221124104"]) def test_1(user): print(user) assert user == "18221124104" # 单参数多值 @pytest.mark.parametrize("user", ["18221124104", "18200000000", "18200000001"]) def test_2(user): print(user) assert user == "18221124104" # 多参数多值 @pytest.mark.parametrize("user,pwd", [("18221124104", 333333), ("18200000000", 333333)]) def test_3(user, pwd): print(user, pwd) # 若要获得多个参数化参数的所有组合,可以堆叠参数化装饰器 @pytest.mark.parametrize("x", [0, 1]) @pytest.mark.parametrize("y", [2, 3]) def test_4(x, y): print("测试数据组合:x->%s, y->%s" % (x, y)) if __name__ == "__main__": time_stamp = time.time_ns() filename = f'test_report_{time_stamp}' pytest.main(["-v", "pytest_mark_parametrize.py", f"--html=report/{filename}.html"])
七、pytest_前置/后置处理
1.利用pytest自带的函数入口
import pytest def setup_module(): print('1. 模块级别前置 setup_module') def teardown_module(): print('1. 模块级别后置 teardown_module') class TestDemo: def setup_class(self): # 类前置 print('2. 类前置 setup_class') def teardown_class(self): # 类后置 print("2. 类后置 teardown_class") def setup(self): # 前置 print("3. 方法前置 setup") def teardown(self): # 后置 print("3. 方法后置 teardown") def test_func1(self): print('4. 测试方法 1') def test_func2(self): print('4. 测试方法 2') if __name__ == '__main__': pytest.main(['-vs', 'pytest_setup_teardown.py'])
2.利用pytest的fixture函数
import pytest # 1. 定义 类前置/后置方法(设定 autouse 为 True,自动为所有的用例自动执行) @pytest.fixture(scope='class', autouse=True) def func1(): print('1. 类前置') # 书写前置方法代码 yield print('1. 类后置') # 书写后置方法代码 # 2. 定义 方法前置/后置方法(设定 autouse 为 True,所有的用例自动执行) @pytest.fixture(scope='function', autouse=True) def func2(): print('2. 方法前置') # 书写前置方法代码 yield print('2. 方法后置') # 书写后置方法代码 # 3. 定义 方法前置方法 (autouse未设值时,默认是False,部分用例执行) @pytest.fixture(scope='function') def func3(): print('3. 方法前置') # 书写前置方法代码 yield print('3. 方法后置') # 书写后置方法代码 class TestDemo: def test_func1(self): print('3. 测试方法1') def test_func2(self, func3): # 部分用例执行 print('3. 测试方法2') if __name__ == '__main__': pytest.main(['-s', 'pytest_fixture_setup_teardown.py'])
八、conftest.py文件
# conftest.py import pytest @pytest.fixture def demo_fixture(): print("这是fixture函数的输出")
# pytest_fixture_conftest.py import pytest def test_01(demo_fixture): print("执行了test_01") def test_02(demo_fixture): print("执行了test_02") if __name__ == '__main__': pytest.main(['-vs', 'pytest_fixture_conftest.py'])
使用场景:(1)每个接口需共用到的token;(2)每个接口需共用到的测试用例数据;(3)每个接口需共用到的配置信息