![](/img/trans.png)
[英]Using fixtures as parameters in @pytest.mark.parametrize
[英]Renaming parameters in pytest.mark.parametrize
我有一個使用目錄中的文件作為參數的代碼:
def get_testcases(directory):
files = list(os.listdir(directory))
testcases = filter(lambda x: x.endswith('.yaml'), files)
for testcase in testcases:
postconf = testcase.replace('.yaml', '.conf')
yield (
os.path.join(directory, testcase),
os.path.join(directory, postconf)
)
def get_pre_configs(directory):
for file in os.listdir(directory):
if file.endswith('.conf'):
yield os.path.join(directory, file)
@pytest.mark.parametrize("pre_config", get_pre_configs('pre_configs'))
@pytest.mark.parametrize("testcase_declaration, testcase_result", get_testcases('testcases'))
def test_foo(pre_config, testcase_declaration, testcase_result):
assert testcase_declaration
assert testcase_result
assert pre_config
它可以按我的需要工作,但我不喜歡 pytest output:
test_interface.py::test_foo[testcases/up.yaml-testcases/up.conf-pre_configs/bad.conf] PASSED [ 16%]
test_interface.py::test_foo[testcases/up.yaml-testcases/up.conf-pre_configs/simple.conf] PASSED [ 33%]
test_interface.py::test_foo[testcases/up.yaml-testcases/up.conf-pre_configs/complicated.conf] PASSED [ 50%]
test_interface.py::test_foo[testcases/down.yaml-testcases/down.conf-pre_configs/bad.conf] PASSED [ 66%]
test_interface.py::test_foo[testcases/down.yaml-testcases/down.conf-pre_configs/simple.conf] PASSED [ 83%]
test_interface.py::test_foo[testcases/down.yaml-testcases/down.conf-pre_configs/complicated.conf] PASSED [100%]
有沒有辦法為測試顯示與傳遞給測試的值不同的名稱? 我想從文件名中刪除目錄名稱和擴展名(僅用於測試名稱,我想將它們“按原樣”傳遞給測試)。
事實證明@pytest.mark.parametrize
(以及@pytest.fixtures
)非常強大。 它們允許您通過指定ids
列表來更改每個測試的名稱。 訣竅是生成 arguments 以進行動態parametrize
。
我重構了你的代碼(見下文)。 給定一個本地目錄,其中包含:
$ find . -type f -name '*.yaml' -o -name '*.conf'
./pre_configs/yikes.conf
./pre_configs/foobar.conf
./testcases/hello.yaml
./testcases/world.yaml
那么 pytest output 是:
collecting ... collected 4 items
test_foo.py::test_foo[yikes-hello] PASSED [ 25%]
test_foo.py::test_foo[yikes-world] PASSED [ 50%]
test_foo.py::test_foo[foobar-hello] PASSED [ 75%]
test_foo.py::test_foo[foobar-world] PASSED [100%]
============================== 4 passed in 0.19s ===============================
這是重構的代碼。 請注意get_testcases()
和get_pre_configs()
如何都返回一個可以用作@pytest.mark.parametrize
dict
kwargs
的字典。 特別是, ids
允許您覆蓋pytest
使用的名稱。
def getfiles(directory, ext):
"""return two lists: fullpath and names (without extension)"""
n = len(ext)
paths, names = zip(*[
(ent.path, ent.name[:-n])
for ent in os.scandir(directory)
if ent.is_file() and ent.name.endswith(ext)])
return paths, names
def get_testcases(directory):
ypaths, names = getfiles(directory, '.yaml')
cpaths = [f'{os.path.splitext(s)[0]}.conf' for s in ypaths]
return {
'argnames': ['testcase_declaration', 'testcase_result'],
'argvalues': zip(ypaths, cpaths),
'ids': names}
def get_pre_configs(directory):
paths, names = getfiles(directory, '.conf')
return {
'argnames': ['pre_config'],
'argvalues': zip(paths), # always wants a list of tuples
'ids': names}
@pytest.mark.parametrize(**get_pre_configs('pre_configs'))
@pytest.mark.parametrize(**get_testcases('testcases'))
def test_foo(pre_config, testcase_declaration, testcase_result):
assert os.path.isfile(pre_config)
assert os.path.isfile(testcase_declaration)
assert testcase_result
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.