Search code examples
pythonpython-3.xpython-unittest

Inheritance for Python unit tests leads to error


When I run the snippet below, I get an error:

'TypeError: __init__() takes 1 positional argument but 2 were given'. 

However, if I remove the unittest.Main() and just create an instance of B: b = B(), it works just fine and calls A's constructor as it should.

EDIT 2: A is not meant to be run as a unit test. Only A, which inherits B.

EDIT: What I want to accomplish with this inheritance (although it's not well-shown in the snippet) is creating a common base class for two unit tests.

import unittest
from unittest import TestCase

class A(TestCase):

    def __init__(self, message):
        print(message)

class B(A):
    def __init__(self):
        super().__init__('It works!')

    def test_function(self):
        print('B - test method')

unittest.main()

Solution

  • According to the documentation, the TestCase constructor has an optional parameter:

    class unittest.TestCase(methodName='runTest')

    But your constructor doesn't:

    class B(A):
        def __init__(self):
            super().__init__('It works!')
    

    That's why when unittest tries to instantiate your test case, the TypeError: __init__() takes 1 positional argument but 2 were given exception you've observed is thrown.


    When you subclass TestCase, you have to account for its parameters. This is best done with varargs *args, **kwargs, because that can forward any number of positional or keyword arguments:

    class A(TestCase):
        def __init__(self, message, *args, **kwargs):
            super().__init__(*args, **kwargs)
            print(message)
    
    
    class B(A):
        def __init__(self, *args, **kwargs):
            super().__init__('It works!', *args, **kwargs)
    
        def test_function(self):
            print('B - test method')
    

    Make sure not to forget to call super().__init__ in A's constructor - this was another one of the problems in your code.