简体   繁体   中英

How to mark.parametrize() a Pytest fixture

This question is similar to How to Parametrize a Pytest Fixture but I'd like to go a step further. Here's what I have so far:

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])

This works

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

I would like to create a parameterized test for the length of instances .

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

There should be 3 tests. The first and the last tests should pass. The second test should fail. How would I set up the test to do this?

I'll note that @pytest.mark.parameterize does exactly the same thing as the parameterized fixture you set up: runs the test once for each parameter. Therefore, I never use it because the indentation gets out of control with any sort of nested structure. I use this template:

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

Your code is good, but you need a comma after the numbers to denote a tuple. Should be (5,), (1,), (3,). I'm not 100% sure that each entry needs to be iterable, so if that doesn't work, try just removing the parenthesis.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM