1

So, I have fixtures defined in conftest.py file with scope="class" as I want to run them before each test class is invoked. The conftest file is placed inside project root directory for it to be visible to every test module.

Now in one of the test modules, I have another setup function which I want to run once for that module only. But the problem is setup_class() method is called before running fixtures defined in conftest.py. Is this expected? I wanted it to be opposite because I want to use something done in the fixtures defined in conftest. How to do that?

Code -

conftest.py:

@pytest.fixture(scope="class")
def fixture1(request):
    #set a

@pytest.fixture(scope="class")
    def fixture1(request):

test_1.py:

   @pytest.mark.usefixtures("fixture_1", "fixture_2")
   class Test1():

      #need this to run AFTER the fixture_1 & fixture_2 
      def setup_class():
          #setup
          #get a set in fixture_1
      
      def test_1()
      .....

I know that I could simply define a fixture in the test file instead of setup_class but then I will have to specify it in arguments of every test method in order it to be invoked by pytest. But suggestions are welcome!

Shivam Mishra
  • 1,731
  • 2
  • 11
  • 29

3 Answers3

0

I have exactly the same problem. Only now I have realized that the problem might be taht the setup_class is called before the fixture >-/ I think that this question is similar to this one Pytest - How to pass an argument to setup_class? And the problem is mixing the unittest and pytest methods. I kind of did what they suggested - I ommitted the setup_class and created a new fixture within the particular test file, calling the fixture in the conftest.py. It works so far. M.

Michala
  • 3
  • 2
  • Could you please provide more details for the answer. Examples of code would be useful here – Eugeny Okulik Nov 03 '22 at 20:27
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Nov 07 '22 at 09:19
0

The problem is that you can use the result of a fixture only in test function (or method) which is run by pytest. Here I can suggest a workaround. But of course I'm not sure if it suites your needs.
The workaround is to call the function from a test method:

conftest.py

@pytest.fixture(scope='class')
def fixture1():
    yield 'MYTEXT'

test_1.py

class Test1:
    def setup_class(self, some_var):
        print(some_var)

    def test_one(self, fixture1):
        self.setup_class(fixture1)
Eugeny Okulik
  • 1,331
  • 1
  • 5
  • 16
0

Fixtures and setup_class are two different paradigms to initialize test functions (and classes). In this case, mixing the two creates a problem: The class-scoped fixtures run when the individual test functions (methods) run. On the other hand, setup_class runs before they do. Hence, it is not possible to access a fixture value (or fixture-modified state) from setup_class.

One of the solutions is to stop using setup_class entirely and stick with a fixtures-only solution which is the preferred way in pytest nowadays (see the note at the beginning).

# conftest.py or the test file:
@pytest.fixture(scope="class")
def fixture_1(request):
    print('fixture_1')

# the test file:
class Test1():
    @pytest.fixture(scope="class", autouse=True)
    def setup(self, fixture_1, request):
        print('Test1.setup')

    def test_a(self):
        print('Test1.test_a')

    def test_b(self):
        print('Test1.test_b')

Note that the setup fixture depends on fixture_1 and hence can access it.

hroncok
  • 1,147
  • 8
  • 12