I'm using the Template Method Pattern for my test cases, i.e. they have the following structure:
Parent(unittest.TestCase)
|
|---- Child1
|---- Child2
|---- Child3
Test cases are defined in the parent. Each child implements a certain different setup.
When I run my tests with pytest (python -m pytest
), I want the inherited tests in Child1 - Child3 to be run, but the ones defined in Parent should not run. They should also not yield a failing test.
How can I do that?
I'm using python_classes=
in pytest.ini
, so tests are not selected based on names. Changing that is not an option.
I tried:
- Making Parent abstract. Result: Parent fails to instantiate, tests are marked as failed.
- Setting
__test__ = False
in Parent. Result: Child tests are also not executed.
I'm using the Template Method Pattern for my test cases, i.e. they have the following structure:
Parent(unittest.TestCase)
|
|---- Child1
|---- Child2
|---- Child3
Test cases are defined in the parent. Each child implements a certain different setup.
When I run my tests with pytest (python -m pytest
), I want the inherited tests in Child1 - Child3 to be run, but the ones defined in Parent should not run. They should also not yield a failing test.
How can I do that?
I'm using python_classes=
in pytest.ini
, so tests are not selected based on names. Changing that is not an option.
I tried:
- Making Parent abstract. Result: Parent fails to instantiate, tests are marked as failed.
- Setting
__test__ = False
in Parent. Result: Child tests are also not executed.
1 Answer
Reset to default 0Use composite inheritance
Source: sqlpey
class Parent: # no inheritance
# treat this class as a test class...
# ... have a setUp method
def setUp(self):
....
# ... define your tests
def test_1(self):
...
def abstract_method(self):
raise Exception("Implement in Child")
class Child1(Parent, unittest.TestCase):
...
Very important: first state your Parent, second TestCase. Otherwise it won't collect/run your tests as expected.
Other Suboptimal solutions
If it's ok to have the tests in the Parent class marked as "passed", you can use the following.
Option 1: Let the abstract method only fail if not implemented in child classes
class Parent(unittest.TestCase):
def my_abstract_method(self):
if(type(self) == Parent):
return
else:
raise Exception("Please implement in sub class.")
Option 2: Let the test not run in parent class
class Parent(unittest.TestCase):
def test_1(self):
if(type(self) == Parent): return
...
Problem: all parent tests will also collected for each child. I.e. if you defined 4 tests in your parent, then run tests of your Child 8 tests will be run (4 tests of the child and 4 of the Parent)