Why do tests in class derivatives rerun parent class tests?

When there is significant overlap in the test setup, it can store DRY stuff for inheritance use. But this causes problems with unnecessary duplication of test execution:

from unittest import TestCase class TestPotato(TestCase): def test_in_parent(self): print 'in parent' class TestSpud(TestPotato): def test_in_child(self): print 'in child' 

Testing of this module is performed by test_in_parent twice.

 $ python -m unittest example in parent .in child .in parent . ---------------------------------------------------------------------- Ran 3 tests in 0.000s OK 

Why? Is it for design? Is it possible to disable it by setting up a test runner in a certain way?

I can solve this problem by moving the setting to an unclosed class, and then use multiple inheritance, but it seems to be a bit hacked and unnecessary.

Note: the same problem occurs for other runners such as nose ( nosetests -s example.py ) and pytest ( py.test example.py )

+6
source share
3 answers

Test testers look for all methods starting with test . Inherited methods are present in the child class, so they are detected as tests to run. To avoid this, you should extract the common code in the parent class and not inherit any real tests.

 from unittest import TestCase class PotatoTestTemplate(TestCase): def setUp(): pass class PotatoTest1(PotatoTestTemplate): def test1(self): pass class PotatoTest2(PotatoTestTemplate): def test1(self): pass 
+4
source

Another workaround I've seen people use is that nested classes will not run as part of nosetests, for example.

 from unittest import TestCase class NotTested: class TestPotato(TestCase): def test_in_parent(self): print 'in parent' class TestSpud(NotTested.TestPotato): def test_in_child(self): print 'in child' 

The workaround that I tried unsuccessfully was to use multiple inheritance, so the TestPotato class extends the object, and TestSpud extends from TestCase and TestPotato for example

 from unittest import TestCase class TestPotato(object): def test_in_parent(self): # still gets ran twice because # nosetests runs anything that starts with test_* :( print 'in parent' class TestSpud(TestCase, TestPotato): def test_in_child(self): print 'in child' 

But that actually didn’t work for me, I would like it to happen because you don’t need to add code nesting ... but it seems like using multiple inheritance is bad anyway

+1
source

If the test setUp from another test class is all you need, you can do this:

 from unittest import TestCase class TestPotato(TestCase): def setUp(self): print('fixtures here') def test_in_parent(self): print 'in parent' class TestSpud(TestCase): def setUp(self): TestPotato.setUp(self) def test_in_child(self): print 'in child' 
+1
source

All Articles