首页 > 解决方案 > 如何标记.parametrize() 一个 Pytest 夹具

问题描述

这个问题类似于How to Parametrize a Pytest Fixture但我想更进一步。这是我到目前为止所拥有的:

import pytest

class TimeLine:
    def __init__(self, s, instances=[0, 0, 0]):
        self.s = s
        self.instances = instances

@pytest.fixture(params=[
    ('foo', [0, 2, 4, 0, 6]),
    ('bar', [2, 5]),
    ('hello', [6, 8, 10])
])
def timeline(request):
    return TimeLine(request.param[0], request.param[1])

这有效

def test_timeline(timeline):
    for instance in timeline.instances:
        assert instance % 2 == 0

我想为instances.

@pytest.mark.parametrize('length', [
     (5), (1), (3)
])
def test_timeline(length, timeline):
   assert len(timeline.instances) == length

应该有3个测试。第一个和最后一个测试应该通过。第二次测试应该失败。我将如何设置测试来做到这一点?

标签: pythonpytest

解决方案


我会注意到 @pytest.mark.parameterize 与您设置的参数化夹具完全相同:为每个参数运行一次测试。因此,我从不使用它,因为任何嵌套结构都会使缩进失控。我使用这个模板:

well_named_params = [1,2,3]  # I move this outside to avoid information overload.

@pytest.fixture(
    params=well_named_params,
    ids=["one","two","three"] # test label
)
def some_param(request):
    """ Run the test once for each item in params.
    Ids just provide a label for pytest. """
    return request.param

你的代码很好,但你需要在数字后面加一个逗号来表示一个元组。应该是 (5,), (1,), (3,)。我不能 100% 确定每个条目都需要是可迭代的,所以如果这不起作用,请尝试删除括号。


推荐阅读