1

I am learning about parameterized tests with pyest. After following the relevant pytest documentation, I came up with this simple example:

import unittest

import pytest


@pytest.fixture(autouse=True, params=['foo', 'bar'])
def foo(request):
    print('fixture')
    print(request.param)


class Foo(unittest.TestCase):
    def setUp(self):
        print('unittest setUp()')

    def test(self):
        print('test')

This gives the following error:

Failed: The requested fixture has no parameter defined for the current test.
E               
E               Requested fixture 'foo' defined in:
E               tests/fixture.py:7

Line 7 is def foo(request):.

What causes this error and how do I fix it?

Code-Apprentice
  • 81,660
  • 23
  • 145
  • 268
  • I normally use `@pytest.mark.parametrise('request', ['foo', 'bar'])`. It doesn't answer your question, but it might work as a quick fix (Where `request` is the name of the argument) – Artyer Aug 22 '17 at 19:41
  • @Artyer Thanks for the suggestion. The docs that I link do not have this, so I'm still interested in learning what I am doing wrong. – Code-Apprentice Aug 22 '17 at 19:43
  • I think the problem is like its mentioned in the error, you don't have defined the parameter, as @Artyer said in his example, he is naming "request" and then passing the values. In your code you pass to the foo function the request argument but there is no parameter on that due you are not defining inside the fixture – Genaro Morales Aug 22 '17 at 19:50
  • @GenaroMorales How does my example differ from the one given in the docs at https://docs.pytest.org/en/latest/fixture.html#parametrizing-fixtures? – Code-Apprentice Aug 22 '17 at 19:56
  • Using the autouse means that all test methods in the class will use this fixture if you remove that you are going to use that fixture only in the method that has the request argument and that method will pass – Genaro Morales Aug 22 '17 at 20:28
  • @GenaroMorales Only the fixture has a `request` argument. The `test()` method does not have any arguments (other than `self`). I want the fixture to apply to all the tests in the `Foo` class. In the example, there is only one test but there can potentially be more. – Code-Apprentice Aug 22 '17 at 20:30
  • Yes, it could be more but you don't have defined any to use the arguments on the other methods – Genaro Morales Aug 22 '17 at 20:38

1 Answers1

1

The goal of fixtures is to pass objects to the test cases, but the fixture you've made doesn't return or yield anything.

Then I'm not sure you can pass objects to a unittest TestCase method, i think it may create some conflicts with the self parameter.

On the other side, it can work with a simple function :

@pytest.fixture(autouse=True, params=['foo', 'bar'])
def foo(request):
    print('fixture')
    print(request.param)
    yield request.param

# class Foo(unittest.TestCase):
#     def setUp(self):
#         print('unittest setUp()')
# 
#     def _test(self):
#         print('test')

def test_fixture(foo):
    assert foo == 'foo'

>>>  1 failed, 1 passed in 0.05 seconds
# test 1 run with foo : OK
# test 2 run with bar : FAILED

EDIT :

Indeed : Why cant unittest.TestCases see my py.test fixtures?

PRMoureu
  • 12,817
  • 6
  • 38
  • 48