0

我是 pytest 的新手,所以请多多包涵。
我正在尝试使用堆栈参数化装饰器来测试多个组合排列,但问题是我如何使用堆栈中其他参数化装饰器的值。

我发现了以下内容:但这并不完全是我正在寻找的
堆叠参数
使用 pytest.mark.parametrize 中的固定装置\

这就是我想要实现的目标:

@pytest.mark.parametrize("environment", ["main", "develop", "ci"])
@pytest.mark.parametrize("model", get_models())
@pytest.mark.parametrize("id", get_ids(environment, model)) #here i tried to use the returned values of environment and model from the above decorators  
def test_ids(environment, model, id):
    another_method(environment, model, id)
    # some logic here

get_ids()根据给定的environment和返回一个 id 列表model
这个解决方案不起作用,因为它引发了一个未解决的参考错误environmentmodel

我想使用参数化装饰器的原因是因为我需要测试 和 的所有排列,environments但希望 pytest 为每个组合生成单独的测试。modelsids

我目前的解决方案是:

@pytest.mark.parametrize("environment", ["main", "develop", "ci"])
@pytest.mark.parametrize("model", get_models())
def test_ids(environment, model):
    ids = get_ids(environment, model)
    for id in ids:
      another_method(environment, model, id)
      # some logic here

这个解决方案有效,但是每个测试都非常长,因为它循环了一长串 id,我更喜欢运行多个小测试,而不是更少的测试但很长。
它使理解测试中发生的事情变得更加困难。
有什么建议吗?

4

1 回答 1

0

我能想到的一种方法是使用钩子。它涉及使用pytest_generate_tests钩子,因为这允许我们对测试进行参数化。

test_id我按以下方式设置的脚本。

def get_models():
    return [1,2]

class TestEnvModelIds:
    envs = ["main", "develop", "ci"]
    model = get_models()

    def test_ids(self, environment, model, id):
        pass

请注意,我们已将测试放在一个类中,这很重要,因为稍后我们想从我们的钩子中访问这些类属性。

真正的魔法发生在下面的函数中,我们将它放在我们conftest.py的测试目录的根目录中。我为两者创建了玩具示例,get_modelsget_ids说明这种方法是可行的。您的实际用例可能略有不同,因为您可能需要从您实际测试的项目中导入这些功能。

def get_ids(env, model):
    data = {
        "main": {
            1: ["a", "b"],
            2: ["c", "d"]
        },
        "develop": {
            1: ["e", "f"],
            2: ["g", "h"]
        },
        "ci": {
            1: ["i", "j"],
            2: ["k", "l"]
        }
    }

    return data[env][model]

def pytest_generate_tests(metafunc):
    if "TestEnvModelIds" == metafunc.cls.__qualname__:
        envs = metafunc.cls.envs
        models = metafunc.cls.model
        argnames = metafunc.fixturenames
        argvalues = []
        
        for env in envs:
            for model in models:
                ids = get_ids(env, model)
                for id_ in ids:
                    argvalues.append((env, model, id_))

        metafunc.parametrize(argnames, argvalues, scope="class")

发生的事情pytest_generate_tests是我们迭代环境,然后是模型,最后是 id。我们创建这些三元组的列表,然后最后用它们参数化我们的测试。

当我们以冗长的方式运行测试套件时,我们可以看到我们成功地生成了所需的每个可能的测试组合。

====================================== test session starts =======================================
platform darwin -- Python 3.9.1, pytest-6.2.2, py-1.10.0, pluggy-0.13.1 -- /Users/DmitryPolonskiy/Desktop/so/bin/python3.9
cachedir: .pytest_cache
rootdir: ***
collected 12 items                                                                               

tests/test_models.py::TestEnvModelIds::test_ids[main-1-a] PASSED                           [  8%]
tests/test_models.py::TestEnvModelIds::test_ids[main-1-b] PASSED                           [ 16%]
tests/test_models.py::TestEnvModelIds::test_ids[main-2-c] PASSED                           [ 25%]
tests/test_models.py::TestEnvModelIds::test_ids[main-2-d] PASSED                           [ 33%]
tests/test_models.py::TestEnvModelIds::test_ids[develop-1-e] PASSED                        [ 41%]
tests/test_models.py::TestEnvModelIds::test_ids[develop-1-f] PASSED                        [ 50%]
tests/test_models.py::TestEnvModelIds::test_ids[develop-2-g] PASSED                        [ 58%]
tests/test_models.py::TestEnvModelIds::test_ids[develop-2-h] PASSED                        [ 66%]
tests/test_models.py::TestEnvModelIds::test_ids[ci-1-i] PASSED                             [ 75%]
tests/test_models.py::TestEnvModelIds::test_ids[ci-1-j] PASSED                             [ 83%]
tests/test_models.py::TestEnvModelIds::test_ids[ci-2-k] PASSED                             [ 91%]
tests/test_models.py::TestEnvModelIds::test_ids[ci-2-l] PASSED                             [100%]

======================================= 12 passed in 0.04s =======================================
于 2021-02-24T12:52:46.343 回答