17

I have a common py.test fixture that I want to use generically in different test files within the same module. After reading the py.test documentation, the suggestion was to add the fixture to a conftest.py file which should make the fixture available to all files in the module. But for some reason, I can't seem to get this common fixture to work with my test class.

#In conftest.py

import pytest

@pytest.fixture
def mock_data(scope="module"):
    return ({'number_of_females_1': 14,
             'number_of_females_2': 3,
             'number_of_females_3': 19,
             'number_of_males_1': 37)} 

Then in my test class file I have

Import pytest
from unittest import TestCase    

@pytest.mark.usefixtures('mgmt_data')
class Test_param_sweeps(TestCase):

    def test_Base_model(self, mgmt_data):
        from pyugend.pyugend.Models import Base_model
        t = Base_model(**mgmt_data)
        assert isinstance(t, Base_model)

The documentation said that I did not have to import the mgmt_data fixture or anything.

The error I get when running this test case is:

self = <pyugend.tests.test_param_sweeps.Test_param_sweeps testMethod=test_Base_model>
result = <TestCaseFunction 'test_Base_model'>

    def run(self, result=None):
        orig_result = result
        if result is None:
            result = self.defaultTestResult()
            startTestRun = getattr(result, 'startTestRun', None)
            if startTestRun is not None:
                startTestRun()

        result.startTest(self)

        testMethod = getattr(self, self._testMethodName)
        if (getattr(self.__class__, "__unittest_skip__", False) or
            getattr(testMethod, "__unittest_skip__", False)):
            # If the class or method was skipped.
            try:
                skip_why = (getattr(self.__class__, '__unittest_skip_why__', '')
                            or getattr(testMethod, '__unittest_skip_why__', ''))
                self._addSkip(result, self, skip_why)
            finally:
                result.stopTest(self)
            return
        expecting_failure_method = getattr(testMethod,
                                           "__unittest_expecting_failure__", False)
        expecting_failure_class = getattr(self,
                                          "__unittest_expecting_failure__", False)
        expecting_failure = expecting_failure_class or expecting_failure_method
        outcome = _Outcome(result)
        try:
            self._outcome = outcome

            with outcome.testPartExecutor(self):
                self.setUp()
            if outcome.success:
                outcome.expecting_failure = expecting_failure
                with outcome.testPartExecutor(self, isTest=True):
>                   testMethod()
E                   TypeError: test_Base_model() missing 1 required positional argument: 'mgmt_data'

/home/krishnab/anaconda3/envs/py35_gu/lib/python3.5/unittest/case.py:600: TypeError

I am not sure that the error is? It says that I am missing a positional argument, but mgmt_data() does not take any arguments and the Base_model() class takes only one argument which is the **mgmt_data.

krishnab
  • 9,270
  • 12
  • 66
  • 123
  • You forgot to include mgmt_data in your arguments. – Shadow Mar 28 '17 at 05:17
  • Oh, I tried it that way as well. But the error is just different. I updated the OP with the new error message. This new message is even more confusing. – krishnab Mar 28 '17 at 05:40

1 Answers1

27

I figured out the answer. The issue was that I was using a Unittest type class instead of a py.test type class. Technically both can work with py.test but only py.test type classes can access fixtures.

So I just changed:

from unittest import TestCase    

@pytest.mark.usefixtures('mgmt_data')
class Test_param_sweeps(TestCase):

in the OP, to the following:

import pytest

@pytest.mark.usefixtures('mgmt_data')
class Test_param_sweeps:

    def test_Base_model(self, mgmt_data):
        from pyugend.pyugend.Models import Base_model
        t = Base_model(**mgmt_data)
        assert isinstance(t, Base_model)

Problem solved.

krishnab
  • 9,270
  • 12
  • 66
  • 123
  • So removing the class inheritance completely worked? Won't pytest just fail to recognize this class as a test case now? You still need to inherit from some kind of TestCase class in order to have pytest recognize that it needs to run those, I believe – frei Feb 18 '21 at 08:39
  • @frei Yeah, I think that the `pytest` package has its own TestCase class. Importing `pytest` will search for all the functions or classes that begin with `test` and then pytest proceeds from there. – krishnab Feb 18 '21 at 22:24
  • You're a life-saver! Spent more than 2h trying to figure out what went wrong.. – diman82 Aug 04 '21 at 13:04
  • 1
    @diman82 glad that it helped. I have been there before, so I understand the frustrations :). – krishnab Aug 04 '21 at 18:52
  • @krishnab is it still working for you ? I'm having trouble to setup your solution I get a missing argument error in my test using the fixture :/ – Simon30 Aug 24 '22 at 12:53