Python unittest – setUpClass() is giving me trouble – why can't I inherit like this?

Question:

I have unittest code like the following:

import unittest

class MyUnitTest(unittest.TestCase):
    def setUpClass(self):
        do_something_expensive_for_all_sets_of_tests()

class MyFirstSetOfTests(MyUnitTest):
    def setUpClass(self):
        super(MyFirstSetOfTests, self).setUpClass()
        do_something_expensive_for_just_these_first_tests()

    def test_one(self):
        ...

    def test_two(self):
        ...

class MySecondSetOfTests(MyUnitTest):
    def setUpClass(self):
        super(MySecondSetOfTests, self).setUpClass()
        do_something_expensive_for_just_these_second_tests()

    def test_one(self):
        ...

    def test_two(self):
        ...

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

When I try to run this code, I get an error like this:

======================================================================
ERROR: setUpClass (__main__.MyFirstSetOfTests)
----------------------------------------------------------------------
TypeError: unbound method setUpClass() must be called with MyFirstSetOfTests instance as first argument (got nothing instead)

----------------------------------------------------------------------
Asked By: tadasajon

||

Answers:

setUpClass must be a class method. From the documentation:

A class method called before tests in an individual class run. setUpClass is called with the class as the only argument and must be decorated as a classmethod():

@classmethod
def setUpClass(cls):
    ...

See Class and Module Fixtures for more details.

Your version is missing the @classmethod decorator:

class MyUnitTest(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        do_something_expensive_for_all_sets_of_tests()

class MyFirstSetOfTests(MyUnitTest):
    @classmethod
    def setUpClass(cls):
        super(MyFirstSetOfTests, cls).setUpClass()
        do_something_expensive_for_just_these_first_tests()

The error is thrown because MyFirstSetOfTests.setUpClass() is called on the class, not on an instance, but you didn’t mark your method as a classmethod and thus it was not passed in the automatic self argument. In the above updated code I used cls instead, to reflect that the name references the class object.

Answered By: Martijn Pieters
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.