Aviran
Aviran

Reputation: 5468

unittest.TestCase setUpClass override and inheritance

As can be seen in the following example, I've defined a BaseClass for all tests, each test case class inherits the base class.

Both classes needs to perform a one time initialization, when test_vehicles.py is executed, I need to make sure that setUpClass of the base class is invoked as well, not sure how to achieve that where @classmethod is in play.

# base.py
import unittest

class BaseClass(unittest.TestCase):
   @classmethod
   def setUpClass(cls):
       # initialize stuff 
       cls.app = app

# test_vehicles.py
class VehiclesTestCase(BaseClass):

    @classmethod
    def setUpClass(cls):
        # initialize stuff 
        cls.vehicle_id = '123'

    def test_get_vehicle(self):
       resp = self.app.get(self.vehicle_id)
       self.assertEqual(resp, True)



if __name__ == '__main__':
    unittest.main()

Upvotes: 2

Views: 3848

Answers (2)

tilman151
tilman151

Reputation: 634

You can use the super method in the inherited classes' setUpClass to access the setUpClass of BaseClass:

super().setUpClass()

If you don't want to call super in each child class, just create an abstract method in BaseClass and call it in setUpClass of BaseClass. VehiclesTestCase now has to implement this abstract method:

class BaseClass(unittest.TestCase):
   @classmethod
   def setUpClass(cls):
       # initialize stuff 
       cls.app = app

   @classmethod
   def _setUpChild(cls):
       raise NotImplementedError


class VehiclesTestCase(BaseClass):

    @classmethod
    def _setUpChild(cls):
        # initialize stuff 
        cls.vehicle_id = '123'

    def test_get_vehicle(self):
       resp = self.app.get(self.vehicle_id)
       self.assertEqual(resp, True)

I would also recommend that BaseClass is not a TestCase if it cannot run by itself. It would always show up in your test report although it has no tests. You can instead use multi-inheritance:

class BaseClass:
   # Stuff

class VehiclesTestCase(BaseClass, unittest.TestCase):
   # Stuff

The order of inheritance is important. Method lookup is done from left to right. This means that BaseClass.setUpClass overrides the setUpClass of TestCase.

Upvotes: 3

kwarunek
kwarunek

Reputation: 12577

Similar question Using super with a class method. More information yoou can get also from https://docs.python.org/3/library/functions.html#super.

Solution: use super function and bound to the class

# test_vehicles.py
class VehiclesTestCase(BaseClass):

    @classmethod
    def setUpClass(cls):
        super(VehiclesTestCase, cls).setUpClass()
        cls.vehicle_id = '123'


if __name__ == '__main__':
    unittest.main()

Upvotes: 4

Related Questions