常用参数

  1. pytest -v -s 文件名/文件夹名
  1. -m:只运行被标记的测试用例
  2. -k:只运行与给定字符串表达式匹配的测试用例
  3. -s:显示详细报告
  4. -q:显示简洁报告
  5. -x:用例失败时立即停止测试
  6. <font style="color:rgb(51, 51, 51);">--maxfail=n</font>:失败n后停止运行测试

参数化

  1. import pytest
  2. @pytest.mark.parametrize('username,password',[('admin','123456'),('cherry','33333')])
  3. def test_Demo1(username,password):
  4. print(username,password)
  5. assert 1 == 1
  6. if __name__ == '__main__':
  7. pytest.main(['-vs','--color=yes','./run.py'])

Pytest 常用参数 - 图1

Pytest.ini文件配置

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

Pytest 常用参数 - 图2

Pytest.fixture

  1. fixture修饰器来标记固定的工厂函数,在其他函数、模块、类或整个工程调用它时会被激活并优先执行,通常会被用于完成预置处理重复操作
  1. 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. 用途1:装饰函数
  1. import pytest
  2. class Test_demo:
  3. # 被装饰过的函数,函数名可以作为变量传递给测试用例,最终在执行用例之前执行这个装饰过的函数
  4. @pytest.fixture()
  5. def before(self):
  6. print('\n-------------->before')
  7. def test_a(self,before):
  8. print('-------->test_a')
  9. assert 1 == 1
  10. 输出结果
  11. run.py::Test_demo::test_a
  12. -------------->before
  13. -------->test_a
  14. PASSED
  15. ============================== 1 passed in 0.01s ==============================
  1. 用途2:装饰类
  1. import pytest
  2. @pytest.fixture()
  3. def before(): # fixture标记的函数可以应用于测试类外部,且在setup之前运行
  4. print('\n-------------->before')
  5. @pytest.mark.usefixtures('before')
  6. class Test_demo:
  7. def setup(self):
  8. print('------>setup')
  9. def test_a(self):
  10. print('-------->test_a')
  11. assert 1 == 1
  12. 输出结果:
  13. run.py::Test_demo::test_a
  14. -------------->before # 发现before自动优先于测试类运行
  15. ------>setup
  16. -------->test_a
  17. PASSED
  18. ============================== 1 passed in 0.01s ==============================
  1. 用途3:自己运行,不用装饰任何其他
  1. import pytest
  2. @pytest.fixture(autouse=True) # 设置为默认运行
  3. def before():
  4. print('\n-------------->before')
  5. # @pytest.mark.usefixtures('before')
  6. class Test_demo:
  7. def setup(self):
  8. print('------>setup')
  9. def test_a(self):
  10. print('-------->test_a')
  11. assert 1 == 1
  12. 输出结果:
  13. run.py::Test_demo::test_a
  14. -------------->before # 发现before自动优先于测试类运行
  15. ------>setup
  16. -------->test_a
  17. PASSED
  18. ============================== 1 passed in 0.01s ==============================
  1. 用途4:设置作用域(**<font style="color:#096DD9;">scope</font>**)
  1. import pytest
  2. @pytest.fixture(autouse=True,scope='function') # 作用域为function,会作用在每个测试用例之前,设置为默认运行
  3. def before():
  4. print('\n------>before')
  5. # @pytest.mark.usefixtures('before')
  6. class Test_demo:
  7. def setup(self):
  8. print('------>setup')
  9. def test_a(self):
  10. print('------>test_a')
  11. assert 1 == 1
  12. def test_b(self):
  13. print('------->test_b')
  14. assert 1 == 1
  15. 作用域function输出结果:
  16. run.py::Test_demo::test_a
  17. ------>before # 运行第一次
  18. ------>setup
  19. ------>test_a
  20. PASSED
  21. run.py::Test_demo::test_b
  22. ------>before # 运行第二次
  23. ------>setup
  24. ------->test_b
  25. PASSED
  26. ============================== 2 passed in 0.01s ==============================
  27. 作用域class输出结果:
  28. run.py::Test_demo::test_a
  29. ------>before # 只运行一次
  30. ------>setup
  31. ------>test_a
  32. PASSED
  33. run.py::Test_demo::test_b ------>setup
  34. ------->test_b
  35. PASSED
  36. ============================== 2 passed in 0.02s ==============================
  1. 用途5:参数化(将返回值传递给测试用例
    1. 返回的值为单个数
  1. import pytest
  2. @pytest.fixture()
  3. def need_data():
  4. return 2 # 返回数字2
  5. class Test_demo:
  6. def test_a(self,need_data):
  7. print('\n-------->test_a')
  8. assert need_data != 3 # 拿到返回值做断言
  9. 输出结果:
  10. run.py::Test_demo::test_a
  11. -------->test_a
  12. PASSED
  13. ============================== 1 passed in 0.03s ==============================
  1. 2. <font style="color:#9254DE;">返回值为列表</font>
  1. import pytest
  2. @pytest.fixture(params=[1,2,3])
  3. def need_data(request):
  4. return request.param # 返回数字2
  5. class Test_demo:
  6. def test_a(self,need_data):
  7. print('\n-------->test_a')
  8. assert need_data != 3 # 拿到返回值做断言
  9. 输出结果:
  10. run.py::Test_demo::test_a[1]
  11. -------->test_a
  12. PASSED
  13. run.py::Test_demo::test_a[2]
  14. -------->test_a
  15. PASSED
  16. run.py::Test_demo::test_a[3]
  17. -------->test_a
  18. FAILED
  19. ================================== FAILURES ===================================
  20. _____________________________ Test_demo.test_a[3] _____________________________
  21. self = <run.Test_demo object at 0x000000000360C100>, need_data = 3
  22. def test_a(self,need_data):
  23. print('\n-------->test_a')
  24. > assert need_data != 3 # 拿到返回值做断言
  25. E AssertionError
  26. run.py:36: AssertionError
  27. =========================== short test summary info ===========================
  28. FAILED run.py::Test_demo::test_a[3] - AssertionError
  29. ========================= 1 failed, 2 passed in 0.37s =========================
  1. 嵌套:一个fixture引用另一个fixture
  1. import pytest
  2. @pytest.fixture()
  3. def fix1():
  4. print('\n-->call fix1')
  5. @pytest.fixture()
  6. def fix2(fix1):
  7. print('-->call fix2')
  8. def test_main(fix2):
  9. assert 1 == 1
  10. 输出结果:
  11. run.py::test_main
  12. -->call fix1
  13. -->call fix2
  14. PASSED
  15. ============================== 1 passed in 0.01s ==============================
  1. 组合:指多个fixture实现遍历组合
  1. import pytest
  2. @pytest.fixture(params=['unittest','pytest'])
  3. def fix1(request):
  4. yield request.param
  5. @pytest.fixture(params=['python','java'])
  6. def fix2(request):
  7. yield request.param
  8. def test_main(fix1,fix2):
  9. print(f'\n{fix1},{fix2}')
  10. assert 1 == 1
  11. 输出结果:
  12. run.py::test_main[unittest-python]
  13. unittest----python
  14. PASSED
  15. run.py::test_main[unittest-java]
  16. unittest----java
  17. PASSED
  18. run.py::test_main[pytest-python]
  19. pytest----python
  20. PASSED
  21. run.py::test_main[pytest-java]
  22. pytest----java
  23. PASSED
  24. ============================== 4 passed in 0.02s ==============================
  1. 覆盖:就近原则,本地fixture优先级高于上级或全局
  1. import pytest
  2. @pytest.fixture()
  3. def fix1(request):
  4. print('\ncall fix1')
  5. @pytest.fixture()
  6. def fix1(request):
  7. print('\ncall fix2')
  8. def test_main(fix1):
  9. assert 1 == 1
  10. 输出结果:
  11. run.py::test_main
  12. call fix2
  13. PASSED
  14. ============================== 1 passed in 0.01s ==============================