常用参数
pytest -v -s 文件名/文件夹名
-m:只运行被标记的测试用例-k:只运行与给定字符串表达式匹配的测试用例-s:显示详细报告-q:显示简洁报告-x:用例失败时立即停止测试<font style="color:rgb(51, 51, 51);">--maxfail=n</font>:失败n后停止运行测试
参数化
import pytest@pytest.mark.parametrize('username,password',[('admin','123456'),('cherry','33333')])def test_Demo1(username,password):print(username,password)assert 1 == 1if __name__ == '__main__':pytest.main(['-vs','--color=yes','./run.py'])

Pytest.ini文件配置
- 避免每次都填参数,文件需要放在项目根目录下
pytest.ini[pytest]# 执行命令addopts = -s -v --color=yes# 用例文件夹testpaths = ./run.py# 用例文件python_files = test*.py# 用例类python_classes = Test*# 用例函数python_funtions = test*# 控制台输出log_cli = 1
- 然后每次只需要输入pytest即可

Pytest.fixture
- fixture修饰器来标记固定的工厂函数,在其他函数、模块、类或整个工程调用它时会被激活并优先执行,通常会被用于完成预置处理和重复操作
fixture(scope='function',params=None,autouse=Flase,ids=None,name=None)
<font style="color:#F5222D;">scope</font>:被标记方法的作用域
<font style="color:#096DD9;">function(default)</font>:作用于每个测试方法,每个test都运行一次
<font style="color:#096DD9;">class</font>:作用于整个类,每个class的所有test只运行一次
<font style="color:#096DD9;">module</font>:作用于整个模块,每个module的所有test只运行一次
<font style="color:#096DD9;">session</font>:作用于整个session(慎用),每个session只运行一次
<font style="color:#F5222D;">params</font>:(list类型)提供参数数据,供调用标记方法的函数使用
<font style="color:#F5222D;">autouse</font>:是否自动运行,默认为False不运行,设置为True自动运行
- 用途1:装饰函数
import pytestclass Test_demo:# 被装饰过的函数,函数名可以作为变量传递给测试用例,最终在执行用例之前执行这个装饰过的函数@pytest.fixture()def before(self):print('\n-------------->before')def test_a(self,before):print('-------->test_a')assert 1 == 1输出结果run.py::Test_demo::test_a-------------->before-------->test_aPASSED============================== 1 passed in 0.01s ==============================
- 用途2:装饰类
import pytest@pytest.fixture()def before(): # fixture标记的函数可以应用于测试类外部,且在setup之前运行print('\n-------------->before')@pytest.mark.usefixtures('before')class Test_demo:def setup(self):print('------>setup')def test_a(self):print('-------->test_a')assert 1 == 1输出结果:run.py::Test_demo::test_a-------------->before # 发现before自动优先于测试类运行------>setup-------->test_aPASSED============================== 1 passed in 0.01s ==============================
- 用途3:自己运行,不用装饰任何其他
import pytest@pytest.fixture(autouse=True) # 设置为默认运行def before():print('\n-------------->before')# @pytest.mark.usefixtures('before')class Test_demo:def setup(self):print('------>setup')def test_a(self):print('-------->test_a')assert 1 == 1输出结果:run.py::Test_demo::test_a-------------->before # 发现before自动优先于测试类运行------>setup-------->test_aPASSED============================== 1 passed in 0.01s ==============================
- 用途4:设置作用域(
**<font style="color:#096DD9;">scope</font>**)
import pytest@pytest.fixture(autouse=True,scope='function') # 作用域为function,会作用在每个测试用例之前,设置为默认运行def before():print('\n------>before')# @pytest.mark.usefixtures('before')class Test_demo:def setup(self):print('------>setup')def test_a(self):print('------>test_a')assert 1 == 1def test_b(self):print('------->test_b')assert 1 == 1作用域function输出结果:run.py::Test_demo::test_a------>before # 运行第一次------>setup------>test_aPASSEDrun.py::Test_demo::test_b------>before # 运行第二次------>setup------->test_bPASSED============================== 2 passed in 0.01s ==============================作用域class输出结果:run.py::Test_demo::test_a------>before # 只运行一次------>setup------>test_aPASSEDrun.py::Test_demo::test_b ------>setup------->test_bPASSED============================== 2 passed in 0.02s ==============================
- 用途5:参数化(将返回值传递给测试用例)
- 返回的值为单个数
import pytest@pytest.fixture()def need_data():return 2 # 返回数字2class Test_demo:def test_a(self,need_data):print('\n-------->test_a')assert need_data != 3 # 拿到返回值做断言输出结果:run.py::Test_demo::test_a-------->test_aPASSED============================== 1 passed in 0.03s ==============================
2. <font style="color:#9254DE;">返回值为列表</font>
import pytest@pytest.fixture(params=[1,2,3])def need_data(request):return request.param # 返回数字2class Test_demo:def test_a(self,need_data):print('\n-------->test_a')assert need_data != 3 # 拿到返回值做断言输出结果:run.py::Test_demo::test_a[1]-------->test_aPASSEDrun.py::Test_demo::test_a[2]-------->test_aPASSEDrun.py::Test_demo::test_a[3]-------->test_aFAILED================================== FAILURES ===================================_____________________________ Test_demo.test_a[3] _____________________________self = <run.Test_demo object at 0x000000000360C100>, need_data = 3def test_a(self,need_data):print('\n-------->test_a')> assert need_data != 3 # 拿到返回值做断言E AssertionErrorrun.py:36: AssertionError=========================== short test summary info ===========================FAILED run.py::Test_demo::test_a[3] - AssertionError========================= 1 failed, 2 passed in 0.37s =========================
- 嵌套:一个fixture引用另一个fixture
import pytest@pytest.fixture()def fix1():print('\n-->call fix1')@pytest.fixture()def fix2(fix1):print('-->call fix2')def test_main(fix2):assert 1 == 1输出结果:run.py::test_main-->call fix1-->call fix2PASSED============================== 1 passed in 0.01s ==============================
- 组合:指多个fixture实现遍历组合
import pytest@pytest.fixture(params=['unittest','pytest'])def fix1(request):yield request.param@pytest.fixture(params=['python','java'])def fix2(request):yield request.paramdef test_main(fix1,fix2):print(f'\n{fix1},{fix2}')assert 1 == 1输出结果:run.py::test_main[unittest-python]unittest----pythonPASSEDrun.py::test_main[unittest-java]unittest----javaPASSEDrun.py::test_main[pytest-python]pytest----pythonPASSEDrun.py::test_main[pytest-java]pytest----javaPASSED============================== 4 passed in 0.02s ==============================
- 覆盖:就近原则,本地fixture优先级高于上级或全局
import pytest@pytest.fixture()def fix1(request):print('\ncall fix1')@pytest.fixture()def fix1(request):print('\ncall fix2')def test_main(fix1):assert 1 == 1输出结果:run.py::test_maincall fix2PASSED============================== 1 passed in 0.01s ==============================
