Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

passing a py.test fixture between test files in a module

Tags:

python

pytest

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.

like image 627
krishnab Avatar asked Mar 28 '17 05:03

krishnab


People also ask

Can I import pytest fixture from another file?

Use Pytest Fixtures Across Multiple Test Files With conftest.py. To make it easier on ourselves, we can define a fixture to use across multiple test files. These fixtures are defined by creating a file called conftest.py. Additionally, we can call separate files that also import the fixture from our configuration file.

Can a pytest fixture use another fixture?

A fixture can use multiple other fixtures. Just like a test method can take multiple fixtures as arguments, a fixture can take multiple other fixtures as arguments and use them to create the fixture value that it returns.

Can we have multiple fixtures in pytest?

Fixtures can also be requested more than once during the same test, and pytest won't execute them again for that test. This means we can request fixtures in multiple fixtures that are dependent on them (and even again in the test itself) without those fixtures being executed more than once.

How many times will a fixture of module scope run?

Fixtures with scope session will only be executed once per session. Every time you run pytest , it's considered to be one session. Scope session is designed for expensive operations like truncating table and loading a test set to the database.


1 Answers

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.

like image 158
krishnab Avatar answered Nov 01 '22 22:11

krishnab