0

I've been trying to solve a python test using pytest but have not been able to find an example configuration that works - though some are close. Here is my case study:

@pytest.fixture
def vil_check():
   code
   return [(v1,v2,v3), (...), (...)]

@pytest.mark.parameterize("v1,v2,v3", vil_check):
def test_one(v1,v2,v3):
      assert v1 < 2
      assert v2 > 5
      ....

I'm trying to follow this example:

@pytest.mark.parametrize("test_input,expected", [("3+5", 8), ("2+4", 6), ("6*9", 42)])
def test_eval(test_input, expected):
    assert eval(test_input) == expected

But using a fixture to supply the list: [("3+5", 8), ("2+4", 6), ("6*9", 42)].

However, this configuration doesn't work:

@pytest.mark.parametrize("v1, v2, v3", vil_check)
def test_max(v1, v2, v3):
   assert abs(v1) <= 5

The error is that pytest doesn't see vil_check return as iterable. There seems to be a way to use pytest_generate_tests to accomplish this but I'm drawing a blank on how to write it.

6
  • You cannot use a fixture in pytest.mark.parametrize, nor can you use it in pytest_generate_tests . Is there a reason why you need a fixture and cannot just use a function here? Commented Dec 9, 2021 at 5:29
  • @MrBeanBremen I need the information that is dynamically created in the function vil_check. This information can will varying which is why I need to parameterize the test so that the number of tests run equals the number of values returned by vil_check. How can I do this using pytest? Commented Dec 9, 2021 at 12:56
  • i still dont get why you need vil_check to be a fixture. Is it like it's being used elsewhere as well? Commented Dec 9, 2021 at 14:10
  • @Shod I don't need it to be a fixture. Can I call it from within the test? How then can I populate the list for pytest.mark.parametrize. I'm asking how to do this given the nature of the case study. Commented Dec 9, 2021 at 14:54
  • Just make the fixture a normal function (e.g. remove the decorator) and use it like you do now. Commented Dec 9, 2021 at 15:22

1 Answer 1

1

As per OP's comment, because vil_check need not be a fixture, here's what you can do - remove the fixture decorator from vil_check and call it in mark.parametrize below:

def vil_check():
   # code
   yield from [(v1,v2,v3), (...), (...)]

@pytest.mark.parametrize("v1,v2,v3", vil_check()):
def test_one(v1,v2,v3):
      assert v1 < 2
      assert v2 > 5
      # code

Few points:

  • you have spelled parametrized wrong, this may give you error if you have set --strict-markers.
  • the decorator should not have a :
  • for performance, i used yield from instead of return in vil_check. This will be efficient in case the list is huge
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you! I made the changes per your suggestions and incorporated the points. The test works as I hoped.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.