imported TestCase does not run setUpClass on second encounter
See original GitHub issuethe issue
I often write a base TestCase
with some generic tests, then use this as a parent class for more derived TestCase
s.
When importing the base TestCase
into other files pytest discovers it and runs it (as does unittest). However pytest does not process setUpClass
on the base TestCase
the second time that it is encountered.
an example
src/
__init__.py
base.py
test_foo.py
test_bar.py
# base.py
import unittest
class BaseTestCase(unittest.TestCase):
@classmethod
def setUpClass(cls):
if cls is BaseTestCase:
raise unittest.SkipTest("skipping base class")
else:
cls.foo = True
def test_called(self):
# should only reach here in subclass
self.assertTrue(self.foo)
# test_foo.py
from .base import BaseTestCase
class TestFoo(BaseTestCase):
pass
# test_bar.py
from .base import BaseTestCase
class TestBar(BaseTestCase):
pass
expected behaviour
2 skips, 2 passes - like unittest
$ python -m unittest -v
skipped 'skipping base class'
test_called (src.test_bar.TestBar) ... ok
skipped 'skipping base class'
test_called (src.test_foo.TestFoo) ... ok
----------------------------------------------------------------------
Ran 2 tests in 0.001s
OK (skipped=2)
actual behaviour
$ pytest -v src
...
src/test_bar.py::BaseTestCase::test_called SKIPPED [ 25%]
src/test_bar.py::TestBar::test_called PASSED [ 50%]
src/test_foo.py::BaseTestCase::test_called FAILED [ 75%]
src/test_foo.py::TestFoo::test_called PASSED [100%]
======================================================= FAILURES =======================================================
_______________________________________________ BaseTestCase.test_called _______________________________________________
self = <src.base.BaseTestCase testMethod=test_called>
def test_called(self):
# should only reach here in subclass
> self.assertTrue(self.foo)
E AttributeError: 'BaseTestCase' object has no attribute 'foo'
src/base.py:15: AttributeError
=============================================== short test summary info ================================================
FAILED src/test_foo.py::BaseTestCase::test_called - AttributeError: 'BaseTestCase' object has no attribute 'foo'
======================================== 1 failed, 2 passed, 1 skipped in 0.07s ========================================
The fail is because the second time that BaseTestCase
is encountered setUpClass
is not run (which would skip it).
short term fix
a quick fix is to use from . import base
to avoid a reference to BaseTestCase
environment
$ python -V
Python 3.7.6
$ pip freeze
attrs==19.3.0
certifi==2020.4.5.1
importlib-metadata==1.6.0
more-itertools==8.2.0
packaging==20.1
pluggy==0.13.0
py==1.8.1
pyparsing==2.4.7
pytest==5.4.1
six==1.14.0
wcwidth==0.1.9
zipp==3.1.0
Issue Analytics
- State:
- Created 3 years ago
- Comments:9 (4 by maintainers)
Top Results From Across the Web
pytest runs imported unittest.TestCase for the second time ...
There are two solutions I can think of now: Never execute test classes that were imported from another module. Execute only those test...
Read more >Unittest setUpClass not working - Stack Overflow
Here is my test code... import unittest class TestRepGen(unittest.TestCase): """ Contains methods for training data testing """ ...
Read more >unittest — Unit testing framework — Python 3.11.1 ...
A testcase is created by subclassing unittest.TestCase . The three individual tests are defined with methods whose names start with the letters test...
Read more >Testing — PythonCert 5.0 documentation
Tests do not run in order, which shouldn't matter, see point 1. ... setUpClass / tearDownClass - these are run before/after each TestCase...
Read more >How to use unittest-based tests with pytest
To run an existing unittest -style test suite using pytest , type: pytest tests. pytest will automatically collect unittest.TestCase subclasses and their ...
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
We want
pytest
to be a drop-in replacement for theunittest
runner, so we’ll need to replicate that behaviour.Thanks to everyone who has contributed to the discussion of this problem!
If pytest must 100% replicate unittest’s semantics then it’s obvious what must be done. If it doesn’t then the simpler solution from user perspective is one from https://github.com/pytest-dev/pytest/issues/7092. That is unless there is a valid use case of running imported test classes at import sites. But even the OP gave an example where it is prevented with an exception: