赞
踩
pytest.mark.parametrize可以实现参数化,它包含的参数有:
#content of test_param.py
#coding=utf-8
import pytest
testdata = [
(3, 4, -1),
(6,3, 3),
]
@pytest.mark.parametrize("a,b,expected", testdata)
def test_diff_v0(a, b, expected):
diff = a - b
assert diff == expected
pytest test_param.py --collect-only
查看收集的用例如下:test_diff_v0[3-4--1]
和test_diff_v0[6-3-3]
D:\Python\program\practic_unittest>pytest test_param.py --collect-only
============================================================================ test session starts =============================================================================
platform win32 -- Python 3.8.4, pytest-6.2.4, py-1.9.0, pluggy-0.13.1
rootdir: D:\Python\program\practic_unittest, configfile: pytest.ini
plugins: allure-pytest-2.8.16
collected 2 items
<Module test_param.py>
<Function test_diff_v0[3-4--1]>
<Function test_diff_v0[6-3-3]>
========================================================================= 2 tests collected in 0.02s =========================================================================
#content of test_param.py
#coding=utf-8
import pytest
testdata = [
(3, 4),
(6,3),
]
@pytest.mark.parametrize("expected", [-1,3])
@pytest.mark.parametrize("a,b", testdata)
def test_diff_v1(a, b, expected):
diff = a - b
assert diff == expected
pytest test_param.py --collect-only
查看收集的用例如下:test_diff_v1[3-4--1]
、test_diff_v1[3-4-3]
、test_diff_v1[6-3--1]
和test_diff_v1[6-3-3]
D:\Python\program\practic_unittest>pytest test_param.py --collect-only
============================================================================ test session starts =============================================================================
platform win32 -- Python 3.8.4, pytest-6.2.4, py-1.9.0, pluggy-0.13.1
rootdir: D:\Python\program\practic_unittest, configfile: pytest.ini
plugins: allure-pytest-2.8.16
collected 4 items
<Module test_param.py>
<Function test_diff_v1[3-4--1]>
<Function test_diff_v1[3-4-3]>
<Function test_diff_v1[6-3--1]>
<Function test_diff_v1[6-3-3]>
========================================================================= 4 tests collected in 0.02s ========================================================================
ids
或者id
赋值,指定用例标识#content of test_param.py
# coding=utf-8
import pytest
testdata = [
(3, 4, -1),
(6, 3, 3),
]
@pytest.mark.parametrize("a,b,expected", testdata, ids=["test1", "test2"])
def test_diff_v2(a, b, expected):
diff = a - b
assert diff == expected
pytest test_param.py --collect-only
查看收集的用例如下:test_diff_v2[test1]
和test_diff_v2[test2]
D:\Python\program\practic_unittest>pytest test_param.py --collect-only
============================================================================ test session starts =============================================================================
platform win32 -- Python 3.8.4, pytest-6.2.4, py-1.9.0, pluggy-0.13.1
rootdir: D:\Python\program\practic_unittest, configfile: pytest.ini
plugins: allure-pytest-2.8.16
collected 2 items
<Module test_param.py>
<Function test_diff_v2[test1]>
<Function test_diff_v2[test2]>
========================================================================= 2 tests collected in 0.02s =========================================================================
-m name
来执行指定用例pytest.param
的参数有:values
:参数值marks
: 参数添加mark标记,可以是单个值也可以是一个列表id
:设置参数的id#content of test_param.py # coding=utf-8 import pytest #利用pytest.param添加 @pytest.mark.parametrize("a,b,expected", [(4,2,1), pytest.param(9,3,6, marks=pytest.mark.xfail,id="expect fail") ,pytest.param(5,3,1,marks=[pytest.mark.first,pytest.mark.xfail],id="test3")], ) def test_diff_v3(a, b, expected): diff = a - b assert diff == expected #content of pytest.ini [pytest] markers=first:mark run first
pytest test_param.py --collect-only
查看收集的用例如下:xfail
标记的test_diff_v3[expect fail]
和test_diff_v3[test3]
D:\Python\program\practic_unittest>pytest test_param.py --collect-only -m xfail
============================================================================ test session starts =============================================================================
platform win32 -- Python 3.8.4, pytest-6.2.4, py-1.9.0, pluggy-0.13.1
rootdir: D:\Python\program\practic_unittest, configfile: pytest.ini
plugins: allure-pytest-2.8.16
collected 3 items / 1 deselected / 2 selected
<Module test_param.py>
<Function test_diff_v3[expect fail]>
<Function test_diff_v3[test3]>
================================================================ 2/3 tests collected (1 deselected) in 0.02s =================================================================
# content of test_param.py # coding=utf-8 import pytest @pytest.fixture(scope="function") def x(request): return request.param * 3 @pytest.fixture(scope="function") def y(request): return request.param * 2 @pytest.mark.parametrize("x, y", [("a", "b")], indirect=True) def test_indirect(x, y): assert x == "aaa" assert y == "bb"
pytest test_param.py
用例执行通过D:\Python\program\practic_unittest>pytest test_param.py
============================================================================ test session starts =============================================================================
platform win32 -- Python 3.8.4, pytest-6.2.4, py-1.9.0, pluggy-0.13.1
rootdir: D:\Python\program\practic_unittest, configfile: pytest.ini
plugins: allure-pytest-2.8.16
collected 1 item
test_param.py::test_indirect[a-b] PASSED [100%]
============================================================================= 1 passed in 0.02s ==============================================================================
test_param.py
中的@pytest.mark.parametrize("x, y", [("a", "b")], indirect=True)
为@pytest.mark.parametrize("x, y", [("a", "b")], indirect=["x"])
后,执行结果是不通过,因为在断言assert y == "bb"
时不通过D:\Python\program\practic_unittest>pytest test_param.py ============================================================================ test session starts ============================================================================= platform win32 -- Python 3.8.4, pytest-6.2.4, py-1.9.0, pluggy-0.13.1 rootdir: D:\Python\program\practic_unittest, configfile: pytest.ini plugins: allure-pytest-2.8.16 collected 1 item test_param.py::test_indirect[a-b] FAILED [100%] ================================================================================== FAILURES ================================================================================== _____________________________________________________________________________ test_indirect[a-b] _____________________________________________________________________________ x = 'aaa', y = 'b' @pytest.mark.parametrize("x, y", [("a", "b")], indirect=["x"]) def test_indirect(x, y): assert x == "aaa" > assert y == "bb" E AssertionError: assert 'b' == 'bb' E - bb E + b test_param.py:16: AssertionError ========================================================================== short test summary info =========================================================================== FAILED test_param.py::test_indirect[a-b] - AssertionError: assert 'b' == 'bb' ============================================================================= 1 failed in 0.13s ==============================================================================
pytest_generate_tests
钩子可以动态确定参数或者fixture范围,通过传入的metafunc
对象可以检查请求上下文,调用metafunc.parametrize()
进行参数化metafunc.parametrize()
的参数值和pytest.mark.parametrize
一样比如需要在多个环境运行脚本,而每个环境的参数不一样,可通过一下方式来实现动态赋值
在conftest.py中定义
# content of test_param.py # coding=utf-8 import pytest def test_compute(param): assert param < 4 #conftest.py def pytest_addoption(parser): parser.addoption("--dev", action="store_true", help="run in dev env,otherwise run in test env") #带--dev参数时默认值时true,不带时为false # action的值store、store_const,store_true,store_false,append,append_const,count,extend def pytest_generate_tests(metafunc): if "param" in metafunc.fixturenames: if metafunc.config.getoption("dev"): name = [1,2,3] else: name = [3,4,5] metafunc.parametrize("param", name)
pytest test_param.py --collect-only
和执行pytest test_param.py --collect-only --dev
查看收集的用例如下:name=[3,4,5]
和name=[1,2,3]
的值D:\Python\program\practic_unittest>pytest test_param.py --collect-only ============================================================================ test session starts ============================================================================= platform win32 -- Python 3.8.4, pytest-6.2.4, py-1.9.0, pluggy-0.13.1 rootdir: D:\Python\program\practic_unittest, configfile: pytest.ini plugins: allure-pytest-2.8.16 collected 3 items <Module test_param.py> <Function test_compute[3]> <Function test_compute[4]> <Function test_compute[5]> ========================================================================= 3 tests collected in 0.02s ========================================================================= D:\Python\program\practic_unittest>pytest test_param.py --collect-only --dev ============================================================================ test session starts ============================================================================= platform win32 -- Python 3.8.4, pytest-6.2.4, py-1.9.0, pluggy-0.13.1 rootdir: D:\Python\program\practic_unittest, configfile: pytest.ini plugins: allure-pytest-2.8.16 collected 3 items <Module test_param.py> <Function test_compute[1]> <Function test_compute[2]> <Function test_compute[3]> ========================================================================= 3 tests collected in 0.02s =========================================================================
如下代码parser.addoption
的action改为append
后(更多action值地址),在执行命令时把输入的值传给参数
# content of test_param.py
# coding=utf-8
import pytest
def test_compute(param):
assert param < 4
#conftest.py
def pytest_addoption(parser):
parser.addoption("--dev", action="apend", help="run in dev env,otherwise run in test env") #带--dev参数时默认值时true,不带时为false
#action的值store、store_const,store_true,store_false,append,append_const,count,extend
def pytest_generate_tests(metafunc):
if "param" in metafunc.fixturenames:
metafunc.parametrize("param",metafunc.config.getoption("dev")) #metafunc.config.getoption检索命令行选项的值,取到的dev值赋给param参数,metafunc.config.getini(name) 检索 ini 样式文件中读取的值
pytest test_param.py --collect-only --dev 3
或者pytest test_param.py --collect-only --dev 3 --dev 45
分别收集到一条/两条用例:test_compute[3]
和test_compute[45]
D:\Python\program\practic_unittest>pytest test_param.py --collect-only --dev 3 ============================================================================ test session starts ============================================================================= platform win32 -- Python 3.8.4, pytest-6.2.4, py-1.9.0, pluggy-0.13.1 rootdir: D:\Python\program\practic_unittest, configfile: pytest.ini plugins: allure-pytest-2.8.16 collected 1 item <Module test_param.py> <Function test_compute[3]> ========================================================================= 1 test collected in 0.02s ========================================================================== D:\Python\program\practic_unittest>pytest test_param.py --collect-only --dev 3 --dev 45 ============================================================================ test session starts ============================================================================= platform win32 -- Python 3.8.4, pytest-6.2.4, py-1.9.0, pluggy-0.13.1 rootdir: D:\Python\program\practic_unittest, configfile: pytest.ini plugins: allure-pytest-2.8.16 collected 2 items <Module test_param.py> <Function test_compute[3]> <Function test_compute[45]> ========================================================================= 2 tests collected in 0.03s =========================================================================
参考文档:https://docs.pytest.org/en/6.2.x/example/parametrize.html#paramexamples
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。