Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python multiple inheritance unittest -

I'm trying to understand what happens when doing multiple inheritance using a unittest.TestCase class.

MyTest_DoesWork outputs what I expect, this is both setUp() and tearDown() being triggered. This is not happening with MyTest_DoesNotWork. Why is this happening? Any clue?

import unittest

class MyClassTest1(object):
    def setUp(self):
        print 'Setting up', self.__class__
    def test_a1(self):
        print "Running test_a1 for class", self.__class__
    def test_a2(self):
        print "Running test_a2 for class", self.__class__
    def tearDown(self):
        print 'Tearing down', self.__class__

class MyClassTest2(object):
    def setUp(self):
        print 'Setting up', self.__class__
    def test_b1(self):
        print "Running test_b1 for class", self.__class__
    def test_b2(self):
        print "Running test_b2 for class", self.__class__
    def tearDown(self):
        print 'Tearing down', self.__class__

class MyTest_DoesNotWork(unittest.TestCase, MyClassTest1, MyClassTest2):
    """
    Output:
    Running test_a1 for class <class '__main__.MyTest_DoesNotWork'>
    .Running test_a2 for class <class '__main__.MyTest_DoesNotWork'>
    .Running test_b1 for class <class '__main__.MyTest_DoesNotWork'>
    .Running test_b2 for class <class '__main__.MyTest_DoesNotWork'>
    """
    pass

class MyTest_DoesWork(MyClassTest1, MyClassTest2, unittest.TestCase):
    """
    Output:
    Setting up <class '__main__.MyTest_DoesWork'>
    Running test_a1 for class <class '__main__.MyTest_DoesWork'>
    Tearing down <class '__main__.MyTest_DoesWork'>
    .Setting up <class '__main__.MyTest_DoesWork'>
    Running test_a2 for class <class '__main__.MyTest_DoesWork'>
    Tearing down <class '__main__.MyTest_DoesWork'>
    .Setting up <class '__main__.MyTest_DoesWork'>
    Running test_b1 for class <class '__main__.MyTest_DoesWork'>
    Tearing down <class '__main__.MyTest_DoesWork'>
    .Setting up <class '__main__.MyTest_DoesWork'>
    Running test_b2 for class <class '__main__.MyTest_DoesWork'>
    Tearing down <class '__main__.MyTest_DoesWork'>
    """
    pass

if __name__ == "__main__":
    unittest.main()
like image 781
luismartingil Avatar asked Sep 19 '13 14:09

luismartingil


People also ask

Is Pytest better than Unittest?

Which is better – pytest or unittest? Although both the frameworks are great for performing testing in python, pytest is easier to work with. The code in pytest is simple, compact, and efficient. For unittest, we will have to import modules, create a class and define the testing functions within that class.

How do you check for inheritance in Python?

Two built-in functions isinstance() and issubclass() are used to check inheritances. The function isinstance() returns True if the object is an instance of the class or other classes derived from it. Each and every class in Python inherits from the base class object .

How do you write a functional test case in python?

First you need to create a test file. Then import the unittest module, define the testing class that inherits from unittest. TestCase, and lastly, write a series of methods to test all the cases of your function's behavior. First, you need to import a unittest and the function you want to test, formatted_name() .

Which of the following component would you use to set up the execution of tests and provides the outcome to the user?

A test runner is a component which set up the execution of tests and provides the outcome to the user.


1 Answers

Python's method resolution order causes this. With your inheritance structure, it is resolving in the order you declared the parent classes, left to right.

So with MyTest_DoesNotWork, python is going to hit the unittest.TestCase implementations of setUp and tearDown, which do not do anything. Because unittest.TestCase.setUp is not written to be cooperative and call other superclass setUp methods, it just stops there and nothing gets printed.

With MyTest_DoesWork, python will instead resolve to MyClassTest1 first. Just like unittest.TestCase, you haven't written your setUp and tearDown methods to cooperatively call superclass methods. So it stops there and never calls the MyClassTest2 methods. So I am guessing that even this actually isn't working as you expected. Change your MyClassTest1 setUp and tearDown methods to print out "MyClassTest1" instead of self.class and you will see that it's the one being called all the time. MyClassTest2 setUp and tearDown are never called.

like image 138
reteptilian Avatar answered Sep 18 '22 13:09

reteptilian