'Why cant unittest.TestCases see my py.test fixtures?
I'm trying to use py.test
's fixtures with my unit tests, in conjunction with unittest
. I've put several fixtures in a conftest.py
file at the top level of the project (as described here), decorated them with @pytest.fixture
, and put their names as arguments to the test functions that require them.
The fixtures are registering correctly, as shown by py.test --fixtures test_stuff.py
, but when I run py.test
, I get NameError: global name 'my_fixture' is not defined
. This appears to only occur when I use subclasses of unittest.TestCase
—but the py.test
docs seem to say that it plays well with unittest
.
Why can't the tests see the fixtures when I use unittest.TestCase
?
Doesn't work:
conftest.py
@pytest.fixture
def my_fixture():
return 'This is some fixture data'
test_stuff.py
import unittest
import pytest
class TestWithFixtures(unittest.TestCase):
def test_with_a_fixture(self, my_fixture):
print(my_fixture)
Works:
conftest.py
@pytest.fixture()
def my_fixture():
return 'This is some fixture data'
test_stuff.py
import pytest
class TestWithFixtures:
def test_with_a_fixture(self, my_fixture):
print(my_fixture)
I'm asking this question more out of curiosity; for now I'm just ditching unittest
altogether.
Solution 1:[1]
While pytest supports receiving fixtures via test function arguments for non-unittest test methods, unittest.TestCase methods cannot directly receive fixture function arguments as implementing that is likely to inflict on the ability to run general unittest.TestCase test suites.
From the note section at the bottom of: https://pytest.org/en/latest/unittest.html
It's possible to use fixtures with unittest.TestCase
es. See that page for more information.
Solution 2:[2]
You can use the pytest fixtures in unittest.TestCase
with the pytest option autouse
. However, if you use the test_
for the unit method using the fixture the following error will appear:
Fixtures are not meant to be called directly,...
### conftest.py
@pytest.fixture
def my_fixture():
return 'This is some fixture data'
One solution is to use a prepare_fixture
method to set fixtures as an attribute of the TestWithFixtures
class, so that fixtures are available to all unit test methods.
### test_stuff.py
import unittest
import pytest
class TestWithFixtures(unittest.TestCase):
@pytest.fixture(autouse=True)
def prepare_fixture(self, my_fixture):
self.myfixture = my_fixture
def test_with_a_fixture(self):
print(self.myfixture)
Solution 3:[3]
define the fixture as an accessible variable, (like
input
in the following example). To define it, userequest.cls.VARIABLE_NAME_YOU_DEFINE = RETURN_VALUE
use
@pytest.mark.usefixtures("YOUR_FIXTURE")
to use fixture outside of the unittest class, inside the unittest class, access the fixture byself.VARIABLE_NAME_YOU_DEFINE
.
e.g.
import unittest
import pytest
@pytest.fixture(scope="class")
def test_input(request):
request.cls.input = {"key": "value"}
@pytest.mark.usefixtures("test_input")
class MyTestCase(unittest.TestCase):
def test_something(self):
self.assertEqual(self.input["key"], "value")
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | constantstranger |
Solution 3 | PillowDaddy |