簡體   English   中英

重命名 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM