
@pytest.mark.parametrize 是 pytest 提供的用于参数化的标记器,在测试用例下需要不同测试数据的场景下使用。比如参数的字符类型与长度测试测试。
参数说明
@pytest.mark.parametrize 需要接收两个参数。第一个参数是字符串,里面定义参数变量;第二个参数是一个列表,列表内值是多个元组,元组的数量即是测试用例的执行次数。元组内的值需要与第一个参数字符串定义的变量对应。
比如 @pytest.mark.parametrize(“n,n1,n2”, [(1, 2, 3), (3, 4, 5), (5, 6, 7)]),被装饰得测试用例的参数需为 n,n1,n2 。
被装饰得测试用例会被执行三次。第一次执行, 1 会传给 n,2 会传给 n1,3 会传给 n3;第二次执行, 3 会传给 n,4 会传给 n1,5 会传给 n3;第三次执行, 5 会传给 n,6 会传给 n1,7 会传给 n3。
参数化测试用例
import pytest
@pytest.mark.parametrize("n, expected", [
(1 + 2, 3),
(2 + 2, 4),
(3 * 3, 9)
])
def test_math(n, expected):
assert n == expected
运行结果
===================================================================== test session starts ======================================================================
collected 3 items
Config::test_math[3-3] PASSED [ 33%]
Config::test_math[4-4] PASSED [ 66%]
Config::test_math[9-9] PASSED [100%]
====================================================================== 3 passed in 0.01s =======================================================================
参数化测试组
import pytest
@pytest.mark.parametrize("n, expected", [(1, 2), (3, 4)])
class TestClass:
def test_simple_case(self, n, expected):
assert n + 1 == expected
def test_weird_simple_case(self, n, expected):
assert (n * 1) + 1 == expected
运行结果:
===================================================================== test session starts ======================================================================
collected 4 items
Config::TestClass::test_simple_case[1-2] PASSED [ 25%]
Config::TestClass::test_simple_case[3-4] PASSED [ 50%]
Config::TestClass::test_weird_simple_case[1-2] PASSED [ 75%]
Config::TestClass::test_weird_simple_case[3-4] PASSED [100%]
====================================================================== 4 passed in 0.01s =======================================================================
参数化模块中测试用例
分配给 pytestmark 全局变量,还可以参数化模块中的所有测试:
import pytest
pytestmark = pytest.mark.parametrize("n,expected", [(1, 2), (2, 4)])
class TestClass:
def test_simple_case(self, n, expected):
assert n + 1 == expected
def test_weird_simple_case(self, n, expected):
assert (n * 1) + 1 == expected
def test_one(n, expected):
assert n+n == expected
def test_two(n, expected):
assert n+n == expected
运行结果:
===================================================================== test session starts ======================================================================
collected 8 items
Config::TestClass::test_simple_case[1-2] PASSED [ 12%]
Config::TestClass::test_simple_case[2-4] FAILED [ 25%]
Config::TestClass::test_weird_simple_case[1-2] PASSED [ 37%]
Config::TestClass::test_weird_simple_case[2-4] FAILED [ 50%]
Config::test_one[1-2] PASSED [ 62%]
Config::test_one[2-4] PASSED [ 75%]
Config::test_two[1-2] PASSED [ 87%]
Config::test_two[2-4] PASSED [100%]
=================================================================== short test summary info ====================================================================
FAILED Config::TestClass::test_simple_case[2-4] - assert (2 + 1) == 4
FAILED Config::TestClass::test_weird_simple_case[2-4] - assert ((2 * 1) + 1) == 4
================================================================= 2 failed, 6 passed in 0.02s ==================================================================
组合参数化
还可以堆叠 parametrize装饰器,获取多个参数的所有组合:
import pytest
@pytest.mark.parametrize("x", [0, 1])
@pytest.mark.parametrize("y", [2, 3])
def test_foo(x, y):
pass
运行结果:
===================================================================== test session starts ======================================================================
collected 4 items
Config::test_foo[2-0] PASSED [ 25%]
Config::test_foo[2-1] PASSED [ 50%]
Config::test_foo[3-0] PASSED [ 75%]
Config::test_foo[3-1] PASSED [100%]
====================================================================== 4 passed in 0.02s =======================================================================
会按照 x=0/y=2
x=1/y=2
x=0/y=3
x=1/y=3
的顺序组合参数。
参数化中应用标记
还可以在 parametrize 中标记单个测试实例,例如自定义的user:
import pytest
@pytest.mark.parametrize(
"n,expected",
[("3+5", 8), ("2+4", 6), pytest.param("6*7", 42, marks=pytest.mark.user)],
)
def test_eval(n, expected):
assert eval(n) == expected
运行 pytest -m user,结果:
===================================================================== test session starts ======================================================================
collected 3 items / 2 deselected / 1 selected
Config::test_eval[6*7-42] PASSED [100%]
=============================================================== 1 passed, 2 deselected in 0.01s ================================================================
参数化中使用 Fixture
@pytest.mark.parametrize 的 indirect(默认为 False ) 参数,当 indirect 不为 False 时,允许将参数化测试中的某些参数传递给fixture,而不是直接作为测试函数的参数。
- indirect = True 时,全部参数都将传递给 fixture :
import pytest
@pytest.fixture()
def one_param_fixture(request):
"""
通过 request.param 获取参数值
"""
return request.param*2
@pytest.fixture()
def one_param_fixture2(request):
"""
通过 request.param 获取参数值
"""
return request.param*3
@pytest.mark.parametrize("one_param_fixture,one_param_fixture2", [(2, 3), (4, 5)], indirect= True)
def test_one_param_fixture(one_param_fixture, one_param_fixture2):
assert False, (one_param_fixture, one_param_fixture2)
运行结果:
===================================================================== test session starts ======================================================================
configfile: pytest.ini
plugins: allure-pytest-2.15.0
collected 2 items
tests\aaaaa.py FF [100%]
=========================================================================== FAILURES ===========================================================================
_________________________________________________________________ test_one_param_fixture[2-3] __________________________________________________________________
one_param_fixture = 4, one_param_fixture2 = 9
@pytest.mark.parametrize("one_param_fixture,one_param_fixture2", [(2, 3), (4, 5)], indirect= True)
def test_one_param_fixture(one_param_fixture, one_param_fixture2):
> assert False, (one_param_fixture, one_param_fixture2)
E AssertionError: (4, 9)
E assert False
tests\aaaaa.py:38: AssertionError
_________________________________________________________________ test_one_param_fixture[4-5] __________________________________________________________________
one_param_fixture = 8, one_param_fixture2 = 15
@pytest.mark.parametrize("one_param_fixture,one_param_fixture2", [(2, 3), (4, 5)], indirect= True)
def test_one_param_fixture(one_param_fixture, one_param_fixture2):
> assert False, (one_param_fixture, one_param_fixture2)
E AssertionError: (8, 15)
E assert False
tests\aaaaa.py:38: AssertionError
=================================================================== short test summary info ====================================================================
FAILED tests/aaaaa.py::test_one_param_fixture[2-3] - AssertionError: (4, 9)
FAILED tests/aaaaa.py::test_one_param_fixture[4-5] - AssertionError: (8, 15)
====================================================================== 2 failed in 0.12s =======================================================================
- indirect 为列表时,参数只传递给 列表中的 fixture :
import pytest
@pytest.fixture()
def one_param_fixture(request):
"""
通过 request.param 获取参数值
"""
return request.param*2
@pytest.fixture()
def one_param_fixture2(request):
"""
通过 request.param 获取参数值
"""
return request.param*3
@pytest.mark.parametrize("one_param_fixture,one_param_fixture2", [(2, 3), (4, 5)], indirect= ["one_param_fixture2"])
def test_one_param_fixture(one_param_fixture, one_param_fixture2):
assert False, (one_param_fixture, one_param_fixture2)
运行结果:
===================================================================== test session starts ======================================================================
configfile: pytest.ini
plugins: allure-pytest-2.15.0
collected 2 items
tests\aaaaa.py FF [100%]
=========================================================================== FAILURES ===========================================================================
_________________________________________________________________ test_one_param_fixture[2-3] __________________________________________________________________
one_param_fixture = 2, one_param_fixture2 = 9
@pytest.mark.parametrize("one_param_fixture,one_param_fixture2", [(2, 3), (4, 5)], indirect= ["one_param_fixture2"])
def test_one_param_fixture(one_param_fixture, one_param_fixture2):
> assert False, (one_param_fixture, one_param_fixture2)
E AssertionError: (2, 9)
E assert False
tests\aaaaa.py:38: AssertionError
_________________________________________________________________ test_one_param_fixture[4-5] __________________________________________________________________
one_param_fixture = 4, one_param_fixture2 = 15
@pytest.mark.parametrize("one_param_fixture,one_param_fixture2", [(2, 3), (4, 5)], indirect= ["one_param_fixture2"])
def test_one_param_fixture(one_param_fixture, one_param_fixture2):
> assert False, (one_param_fixture, one_param_fixture2)
E AssertionError: (4, 15)
E assert False
tests\aaaaa.py:38: AssertionError
=================================================================== short test summary info ====================================================================
FAILED tests/aaaaa.py::test_one_param_fixture[2-3] - AssertionError: (2, 9)
FAILED tests/aaaaa.py::test_one_param_fixture[4-5] - AssertionError: (4, 15)
====================================================================== 2 failed in 0.12s =======================================================================
THEEND

© 转载需要保留原始链接,未经明确许可,禁止商业使用。CC BY-NC-ND 4.0