根据 json 文件中的列表测试数据对测试进行参数化
Parametrize the test based on the list test-data from a json file
当测试有一个 different/multiple 测试数据列表时,有没有办法参数化测试?
example_test_data.json
{ "test_one" : [1,2,3], # this is the case, where the `test_one` test need to be parametrize.
"test_two" : "split",
"test_three" : {"three":3},
"test_four" : {"four":4},
"test_set_comparison" : "1234"
}
目录结构:
- 主要--
- conftest.py # 我的灯具的 conftest 文件
- 测试用例
- project_1
(包含这些文件 -- test_suite_1.py、config.json)
- project_2
(包含这些文件 -- test_suite_2.py、config.json)
- 工作流程
- 库
在顶级目录级别的 conftest.py 中使用以下代码,能够 get/map 来自特定测试用例的 json 文件的测试数据。
@pytest.yield_fixture(scope="class", autouse=True)
def test_config(request):
f = pathlib.Path(request.node.fspath.strpath)
print "File : %s" % f
config = f.with_name("config.json")
print "Config json file : %s" % config
with config.open() as fd:
testdata = json.loads(fd.read())
print "test data :", testdata
yield testdata
@pytest.yield_fixture(scope="function", autouse=True)
def config_data(request, test_config):
testdata = test_config
test = request.function.__name__
print "Class Name : %s" % request.cls.__name__
print "Testcase Name : %s" % test
if test in testdata:
test_args = testdata[test]
yield test_args
else:
yield {}
就我而言:
@pytest.yield_fixture(scope="function", autouse=True)
def config_data(request, test_config):
testdata = test_config
test = request.function.__name__
print "Class Name : %s" % request.cls.__name__
print "Testcase Name : %s" % test
if test in testdata:
test_args = testdata[test]
if isinstance(test_args, list):
# How to parametrize the test
# yield test_args
else:
yield {}
我会在 pytest_generate_tests
钩子中处理特殊的参数化情况:
# conftest.py
import json
import pathlib
import pytest
@pytest.fixture(scope="class")
def test_config(request):
f = pathlib.Path(request.node.fspath.strpath)
config = f.with_name("config.json")
with config.open() as fd:
testdata = json.loads(fd.read())
yield testdata
@pytest.fixture(scope="function")
def config_data(request, test_config):
testdata = test_config
test = request.function.__name__
if test in testdata:
test_args = testdata[test]
yield test_args
else:
yield {}
def pytest_generate_tests(metafunc):
if 'config_data' not in metafunc.fixturenames:
return
config = pathlib.Path(metafunc.module.__file__).with_name('config.json')
testdata = json.loads(config.read_text())
param = testdata.get(metafunc.function.__name__, None)
if isinstance(param, list):
metafunc.parametrize('config_data', param)
一些注意事项:yield_fixture
is deprecated 所以我用普通的 fixture
替换了它。此外,在 return 值的固定装置中不需要 autouse=True
- 无论如何你都可以调用它们。
我使用的示例测试和配置:
# testcases/project_1/config.json
{
"test_one": [1, 2, 3],
"test_two": "split"
}
# testcases/project_1/test_suite_1.py
def test_one(config_data):
assert config_data >= 0
def test_two(config_data):
assert config_data == 'split'
# testcases/project_2/config.json
{
"test_three": {"three": 3},
"test_four": {"four": 4}
}
# testcases/project_2/test_suite_2.py
def test_three(config_data):
assert config_data['three'] == 3
def test_four(config_data):
assert config_data['four'] == 4
运行 测试结果:
$ pytest -vs
============================== test session starts ================================
platform linux -- Python 3.6.5, pytest-3.4.1, py-1.5.3, pluggy-0.6.0 --
/data/gentoo64/usr/bin/python3.6
cachedir: .pytest_cache
rootdir: /data/gentoo64/home/u0_a82/projects/Whosebug/so-50815777, inifile:
plugins: mock-1.6.3, cov-2.5.1
collected 6 items
testcases/project_1/test_suite_1.py::test_one[1] PASSED
testcases/project_1/test_suite_1.py::test_one[2] PASSED
testcases/project_1/test_suite_1.py::test_one[3] PASSED
testcases/project_1/test_suite_1.py::test_two PASSED
testcases/project_2/test_suite_2.py::test_three PASSED
testcases/project_2/test_suite_2.py::test_four PASSED
============================ 6 passed in 0.12 seconds =============================
当测试有一个 different/multiple 测试数据列表时,有没有办法参数化测试?
example_test_data.json
{ "test_one" : [1,2,3], # this is the case, where the `test_one` test need to be parametrize.
"test_two" : "split",
"test_three" : {"three":3},
"test_four" : {"four":4},
"test_set_comparison" : "1234"
}
目录结构:
- 主要--
- conftest.py # 我的灯具的 conftest 文件
- 测试用例
- project_1 (包含这些文件 -- test_suite_1.py、config.json)
- project_2 (包含这些文件 -- test_suite_2.py、config.json)
- 工作流程
- 库
在顶级目录级别的 conftest.py 中使用以下代码,能够 get/map 来自特定测试用例的 json 文件的测试数据。
@pytest.yield_fixture(scope="class", autouse=True)
def test_config(request):
f = pathlib.Path(request.node.fspath.strpath)
print "File : %s" % f
config = f.with_name("config.json")
print "Config json file : %s" % config
with config.open() as fd:
testdata = json.loads(fd.read())
print "test data :", testdata
yield testdata
@pytest.yield_fixture(scope="function", autouse=True)
def config_data(request, test_config):
testdata = test_config
test = request.function.__name__
print "Class Name : %s" % request.cls.__name__
print "Testcase Name : %s" % test
if test in testdata:
test_args = testdata[test]
yield test_args
else:
yield {}
就我而言:
@pytest.yield_fixture(scope="function", autouse=True)
def config_data(request, test_config):
testdata = test_config
test = request.function.__name__
print "Class Name : %s" % request.cls.__name__
print "Testcase Name : %s" % test
if test in testdata:
test_args = testdata[test]
if isinstance(test_args, list):
# How to parametrize the test
# yield test_args
else:
yield {}
我会在 pytest_generate_tests
钩子中处理特殊的参数化情况:
# conftest.py
import json
import pathlib
import pytest
@pytest.fixture(scope="class")
def test_config(request):
f = pathlib.Path(request.node.fspath.strpath)
config = f.with_name("config.json")
with config.open() as fd:
testdata = json.loads(fd.read())
yield testdata
@pytest.fixture(scope="function")
def config_data(request, test_config):
testdata = test_config
test = request.function.__name__
if test in testdata:
test_args = testdata[test]
yield test_args
else:
yield {}
def pytest_generate_tests(metafunc):
if 'config_data' not in metafunc.fixturenames:
return
config = pathlib.Path(metafunc.module.__file__).with_name('config.json')
testdata = json.loads(config.read_text())
param = testdata.get(metafunc.function.__name__, None)
if isinstance(param, list):
metafunc.parametrize('config_data', param)
一些注意事项:yield_fixture
is deprecated 所以我用普通的 fixture
替换了它。此外,在 return 值的固定装置中不需要 autouse=True
- 无论如何你都可以调用它们。
我使用的示例测试和配置:
# testcases/project_1/config.json
{
"test_one": [1, 2, 3],
"test_two": "split"
}
# testcases/project_1/test_suite_1.py
def test_one(config_data):
assert config_data >= 0
def test_two(config_data):
assert config_data == 'split'
# testcases/project_2/config.json
{
"test_three": {"three": 3},
"test_four": {"four": 4}
}
# testcases/project_2/test_suite_2.py
def test_three(config_data):
assert config_data['three'] == 3
def test_four(config_data):
assert config_data['four'] == 4
运行 测试结果:
$ pytest -vs
============================== test session starts ================================
platform linux -- Python 3.6.5, pytest-3.4.1, py-1.5.3, pluggy-0.6.0 --
/data/gentoo64/usr/bin/python3.6
cachedir: .pytest_cache
rootdir: /data/gentoo64/home/u0_a82/projects/Whosebug/so-50815777, inifile:
plugins: mock-1.6.3, cov-2.5.1
collected 6 items
testcases/project_1/test_suite_1.py::test_one[1] PASSED
testcases/project_1/test_suite_1.py::test_one[2] PASSED
testcases/project_1/test_suite_1.py::test_one[3] PASSED
testcases/project_1/test_suite_1.py::test_two PASSED
testcases/project_2/test_suite_2.py::test_three PASSED
testcases/project_2/test_suite_2.py::test_four PASSED
============================ 6 passed in 0.12 seconds =============================