【问题标题】:pytest.skip within pytest_generate_tests skips all test functions in module instead of specific testspytest_generate_tests 中的 pytest.skip 跳过模块中的所有测试函数而不是特定测试
【发布时间】:2020-11-21 05:19:38
【问题描述】:

我正在使用 pytest_generate_tests 挂钩使用在外部 YAML 文件中定义的变量参数化 pytest 测试。变量文件的名称在 pytest 命令行 (--params_file) 上指定。只有模块中的一些测试函数被参数化并且需要这个文件中的变量。因此,定义变量的命令行选项是可选参数。如果命令行中省略了可选参数,那么我希望 pytest 只“跳过”那些需要外部参数化变量的测试函数,只运行未参数化的“其他”测试。问题是,如果省略命令行选项,pytest 将跳过所有测试函数,而不仅仅是需要参数的测试函数。

这里是测试模块文件:

def test_network_validate_1(logger, device_connections,):

  ### Test code omitted.....


def test_lsp_throttle_timers(params_file, logger, device_connections):

  ### Test code omitted.....

def test_network_validate_2(logger, device_connections,):

  ### Test code omitted.....

conftest.py 中的 pytest_generate_tests 钩子:

# Note, I tried scope at function level as well but that did not help
@pytest.fixture(scope='session')
def params_file(request):
    pass

def pytest_generate_tests(metafunc):
  
    ### Get Pytest rootdir
    rootdir = metafunc.config.rootdir

    print(f"*********** Test Function: {metafunc.function.__name__}")

    if "params_file" in metafunc.fixturenames:
        print("*********** Hello Silver ****************")
        if metafunc.config.getoption("--params_file"):

            #################################################################
            # Params file now located as a separate command line argument for
            # greater flexibility
            #################################################################
            params_file = metafunc.config.getoption("--params_file")
            params_doc = dnet_generic.open_yaml_file(Path(rootdir, params_file),
                                                    loader_type=yaml.Loader)

            test_module = metafunc.module.__name__
            test_function = metafunc.function.__name__
            names,values = dnet_generic.get_test_parameters(test_module,
                                                            test_function,
                                                            params_doc,)

            metafunc.parametrize(names, values )
        else:
            pytest.skip("This test requires the params_file argument")

当 params_file 选项存在时,一切正常:

pytest isis/test_isis_lsp_throttle.py --testinfo topoA_r28.yml --ulog -s --params_file common/topoA_params.yml  --collect-only
===================================================================================== test session starts =====================================================================================
platform linux -- Python 3.7.4, pytest-3.7.0, py-1.8.0, pluggy-0.13.0
rootdir: /home/as2863/pythonProjects/p1-automation, inifile: pytest.ini
plugins: csv-2.0.1, check-0.3.5, pylama-7.6.6, dependency-0.4.0, instafail-0.4.0, ordering-0.6, repeat-0.7.0, reportportal-5.0.3
collecting 0 items                                                                                                                                                                            *********** Test Function: test_network_validate_1
*********** Test Function: test_lsp_throttle_timers
*********** Test Function: test_network_validate_2
collected 3 items
<Package '/home/as2863/pythonProjects/p1-automation/isis'>
  <Module 'test_isis_lsp_throttle.py'>
    <Function 'test_network_validate_1'>
    <Function 'test_lsp_throttle_timers'>
    <Function 'test_network_validate_2'>

================================================================================ no tests ran in 0.02 seconds =================================================================================                                                                                                                                                                            

当 params_file 选项被省略时,您可以看到没有运行任何测试,并且打印语句显示它甚至没有尝试在“test_network_validate_2”上运行 pytest_generate_tests

pytest isis/test_isis_lsp_throttle.py --testinfo topoA_r28.yml --ulog -s  --collect-only                         ===================================================================================== test session starts =====================================================================================
platform linux -- Python 3.7.4, pytest-3.7.0, py-1.8.0, pluggy-0.13.0
rootdir: /home/as2863/pythonProjects/p1-automation, inifile: pytest.ini
plugins: csv-2.0.1, check-0.3.5, pylama-7.6.6, dependency-0.4.0, instafail-0.4.0, ordering-0.6, repeat-0.7.0, reportportal-5.0.3
collecting 0 items

*********** Test Function: test_network_validate_1
*********** Test Function: test_lsp_throttle_timers
*********** Hello Silver ****************
collected 0 items / 1 skipped

================================================================================== 1 skipped in 0.11 seconds ==================================================================================

【问题讨论】:

  • 这很奇怪 - 所以基本上如果你有一个空的pytest_generate_tests 不会生成测试?
  • 正确。没有生成测试
  • 嗯 - 如果你完全删除 pytest_generate_tests 会怎样?这应该与空的效果相同。如果仍然表现相同,则一定有其他问题......
  • 如果我完全注释掉 pytest_generate_tests(在 conftest.py 中),那么所有 3 个测试都会被收集;带或不带 --params_file 命令行参数。
  • 所以,要确保:如果你只写def pytest_generate_tests(metafunc): pass 没有收集测试?这很奇怪……

标签: python pytest


【解决方案1】:

正如在 cmets 中的讨论中发现的那样,您不能在 pytest_generate_tests 中使用 pytest.skip,因为它适用于模块范围。要跳过具体测试,您可以执行以下操作:

@pytest.fixture
def skip_test():
    pytest.skip('Some reason')

def pytest_generate_tests(metafunc):
    if "params_file" in metafunc.fixturenames:
        if metafunc.config.getoption("--params_file"):
            ...
            metafunc.parametrize(names, values )
        else:
            metafunc.fixturenames.insert(0, 'skip_test')

例如您引入一个将跳过具体测试的夹具,并将此夹具添加到测试中。确保将其作为第一个夹具插入,这样就不会执行其他夹具。

【讨论】:

  • 成功了!优秀的解决方案。我什至不知道您可以使用 metafunc.fixturenames.insert() 将夹具动态插入到测试函数中
猜你喜欢
  • 2012-07-11
  • 1970-01-01
  • 2018-01-22
  • 2010-10-20
  • 2014-04-24
  • 1970-01-01
  • 2018-08-10
  • 1970-01-01
  • 2013-06-04
相关资源
最近更新 更多