In Python's unittest
framework, it is a fairly common idiom to use inheritance on a base set of tests to apply an entire set of tests to a new problem, and occasionally to add additional tests. A trivial example would be:
from unittest import TestCase
class BaseTestCase(TestCase):
VAR = 3
def test_var_positive(self):
self.assertGreaterEqual(self.VAR, 0)
class SubTestCase(BaseTestCase):
VAR = 8
def test_var_even(self):
self.assertTrue(self.VAR % 2 == 0)
Which, when run, runs 3 tests:
$ python -m unittest -v
test_var_positive (test_unittest.BaseTestCase) ... ok
test_var_even (test_unittest.SubTestCase) ... ok
test_var_positive (test_unittest.SubTestCase) ... ok
----------------------------------------------------------------------
Ran 3 tests in 0.000s
This is particularly useful if you are testing a class hierarchy, where each subclass is a subtype of the parent classes, and should thus be able to pass the parent class's test suite in addition to its own.
I would like to switch over to using pytest
, but I have a lot of tests that are structured this way. From what I can tell, pytest
intends to replace most of the functionality of TestCase
classes with fixtures, but is there a pytest idiom that allows test inheritance, and if so what is it?
I am aware that pytest
can be used to run unittest
-style tests, but the support is limited, and I would like to use some of the "will never be supported" features of pytest
in my tests.
pytest is a very robust framework that comes with lots of features. One such feature is the autouse fixtures, a.k.a xUnit setup on steroids. They are a special type of fixture that gets invoked automatically, and its main use case is to act as a setup/teardown function.
conftest.py is where you setup test configurations and store the testcases that are used by test functions. The configurations and the testcases are called fixture in pytest. The test_*. py files are where the actual test functions reside.
The simplest way to skip a test is to mark it with the skip decorator which may be passed an optional reason . It is also possible to skip imperatively during test execution or setup by calling the pytest. skip(reason) function. This is useful when it is not possible to evaluate the skip condition during import time.
pytest supports running Python unittest -based tests out of the box. It's meant for leveraging existing unittest -based test suites to use pytest as a test runner and also allow to incrementally adapt the test suite to take full advantage of pytest's features.
Pytest allows you to group test cases in classes, so it naturally has support for test case inheritance.
When rewriting your unittest
tests to pytest
tests, remember to follow pytest's naming guidelines:
Test
test_
Failing to comply with this naming scheme will prevent your tests from being collected and executed.
Your tests rewritten for pytest would look like this:
class TestBase:
VAR = 3
def test_var_positive(self):
assert self.VAR >= 0
class TestSub(TestBase):
VAR = 8
def test_var_even(self):
assert self.VAR % 2 == 0
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With