我不知道为什么将here提到的代码修改为以下内容不起作用?这些变量在测试内部不可访问,并且尽管范围设置为类,但在每次测试之前都会调用设置。任何指示都会非常有帮助。谢谢
#conftest.py
def pytest_addoption(parser):
parser.addoption("--data", action="store", default="1,2 3,4 5,6", help="Data for parametrization")
def pytest_generate_tests(metafunc):
data_str = metafunc.config.getoption("data")
# data_list = [(1, 2), (3, 4), (5, 6)]
data_list = [tuple(map(int, item.split(','))) for item in data_str.split()]
# metafunc.parametrize("data", data_list, indirect=True)
metafunc.parametrize("data", data_list, scope="class")
# @pytest.fixture(scope="class")
# def data(request):
# return request.param
#test_code.py
import pytest
class Test1():
@pytest.fixture(scope="class", autouse=True)
def setup(self, data, request):
print(data)
[self.a, self.b] = list(data)
self.c = self.a + self.b
print('Test1.setup')
def test_a(self):
print("Test1.test_a")
print(f'Test1.test_a - {self.a}, {self.b}, {self.c}')
self.d = self.c * 2
def test_b(self):
print("Test1.test_b")
print(f'Test1.test_b - {self.d}')
问题应该出在 pytest_generate_tests 上,因为我认为每个测试都会调用它?!
您的代码的问题是在
setup()
函数中使用类范围。 setup 函数不是类方法:它是实例方法。此外,我认为使用类太复杂了。我更喜欢使用测试函数。为此,我重新设计和重新组织测试如下:
#!/usr/bin/env python3
# conftest.py
import json
import pytest
def pytest_addoption(parser: pytest.Parser):
parser.addoption(
"--data",
action="store",
default="[[1, 2], [3, 4], [5, 6]]",
help="Data for parametrization",
)
def pytest_generate_tests(metafunc: pytest.Metafunc):
# Only parametrize for the 'data' fixture
if "data" not in metafunc.fixturenames:
return
# Using pytest.param() gives us the option
# to assign an ID to the test data
data_list = [
pytest.param(data, id=f"a={data[0]}, b={data[1]}")
for data in json.loads(metafunc.config.getoption("data"))
]
metafunc.parametrize("data", data_list, scope="session")
@pytest.fixture(scope="session")
def c_value(data):
return sum(data)
@pytest.fixture(scope="session")
def d_value(c_value):
return c_value * 2
# test_code.py
import logging
def test_a(data, c_value):
logging.debug("data=%r", data)
logging.debug("c_value=%r", c_value)
def test_b(data, c_value, d_value):
logging.debug("data=%r", data)
logging.debug("c_value=%r", c_value)
logging.debug("d_value=%r", d_value)
# pyproject.toml
[tool.pytest.ini_options]
log_cli = "true"
log_level = "DEBUG"
log_format = "%(levelname)s | %(filename)s(%(lineno)d) | %(funcName)s | %(message)s"
markers = ["slow"]
输出:
$ pytest -s -v
========================================== test session starts ===========================================
platform linux -- Python 3.12.4, pytest-8.3.1, pluggy-1.5.0 -- /var/tmp/venv/sandbox/bin/python
cachedir: .pytest_cache
rootdir: /home/haiv/temp/so/pytest-parametrize-cmdline
configfile: pyproject.toml
plugins: check-2.3.1, pythonpath-0.7.3, assume-2.4.3, anyio-4.4.0
collected 6 items
test_code.py::test_a[a=1, b=2]
--------------------------------------------- live log call ----------------------------------------------
DEBUG | test_code.py(6) | test_a | data=[1, 2]
DEBUG | test_code.py(7) | test_a | c_value=3
PASSED
test_code.py::test_b[a=1, b=2]
--------------------------------------------- live log call ----------------------------------------------
DEBUG | test_code.py(11) | test_b | data=[1, 2]
DEBUG | test_code.py(12) | test_b | c_value=3
DEBUG | test_code.py(13) | test_b | d_value=6
PASSED
test_code.py::test_a[a=3, b=4]
--------------------------------------------- live log call ----------------------------------------------
DEBUG | test_code.py(6) | test_a | data=[3, 4]
DEBUG | test_code.py(7) | test_a | c_value=7
PASSED
test_code.py::test_b[a=3, b=4]
--------------------------------------------- live log call ----------------------------------------------
DEBUG | test_code.py(11) | test_b | data=[3, 4]
DEBUG | test_code.py(12) | test_b | c_value=7
DEBUG | test_code.py(13) | test_b | d_value=14
PASSED
test_code.py::test_a[a=5, b=6]
--------------------------------------------- live log call ----------------------------------------------
DEBUG | test_code.py(6) | test_a | data=[5, 6]
DEBUG | test_code.py(7) | test_a | c_value=11
PASSED
test_code.py::test_b[a=5, b=6]
--------------------------------------------- live log call ----------------------------------------------
DEBUG | test_code.py(11) | test_b | data=[5, 6]
DEBUG | test_code.py(12) | test_b | c_value=11
DEBUG | test_code.py(13) | test_b | d_value=22
PASSED
=========================================== 6 passed in 0.02s ============================================
讨论
json.loads()
data_list
,我使用 pytest.param()
,我可以命名数据,从而得到更详细的测试名称。conftest.py
所以test_code.py
很干净logging
而不是 print
,因为 logging
比 print
提供更多功能、更多细节。此外,我可以通过编辑来控制日志输出 pyproject.toml