How to use same unit test for different implementations in python?

I have been looking for it and got a couple of example like:

  • Eli Bendersky's Python unit testing: parametrized test cases

But what helped me the most was vegard's answer about making a class factory which would take parameters and create the TestCase accordingly

The function takes the parameters of the parameterised test case and the actual TestCase class can refer to them without any problems.

Here is an example, take a foo.py file with:

import unittest

def make_test_case(x):
    class MyTestCase(unittest.TestCase):
        def test_foo(self):
            self.assertEquals(x, 1)

    return MyTestCase

class ConcreteTestCase(make_test_case(1)): 
    pass

Then run the test(s):

python -m unittest -v foo

Basically this is very flexible and adapted really well to my usecase.


Basically you need to parametrized you tests with function.

For unittest you can use ddt

@ddt
class ProblemTestCase(unittest.TestCase):
    def test_specific_input(self):
        self.assertTrue(function_a("specific input"))

    @data(function_a, function_b)
    def test_generic_input_one(self, function):
        result = function("input 1")
        self.assertFalse(result)

    @data(function_a, function_b)
    def test_generic_input_two(self, function):
        result = function("input 2")
        self.assertTrue(result)

Alternatively you can use just plain OOP:

class AbstractTestCase(object):

    def test_generic_input_one(self):
        result = self.function("input 1")
        self.assertFalse(result)

    def test_generic_input_two(self):
        result = self.function("input 2")
        self.assertTrue(result)

class TestsFunctionA(AbstractTestCase, unittest.TestCase):

    def function(self, param):
        return function_a(param)

    def test_specific_input(self):
        self.assertTrue(self.function("specific input"))

class TestsFunctionB(AbstractTestCase, unittest.TestCase):

    def function(self, param):
        return function_b(param)

    def test_another_specific_input(self):
        self.assertTrue(self.function("another specific input"))