¿Cómo ejecutar el mismo caso de prueba para diferentes clases?

Tengo varias clases que comparten algunos invariantes y tienen una interfaz común, y me gustaría ejecutar automáticamente la misma prueba para cada una de ellas.

Como ejemplo, supongamos que tengo varias clases que implementan diferentes enfoques para la partición de un conjunto de datos. El invariante común aquí sería que, para todas estas clases, la unión sobre todas las particiones debe ser igual al conjunto de datos original.

Lo que actualmente tengo se ve algo como esto:

class PartitionerInvariantsTests(unittest.TestCase): def setUp(self): self.testDataSet = range(100) # create test-data-set def impl(self, partitioner): self.assertEqual(self.testDataSet, chain.from_iterable(partitioner(self.testDataSet)) 

Luego agrego una función diferente que llama a impl para cada una de las clases que quiero probar con una instancia de esa clase. El problema con esto se hace evidente cuando se hace esto para más de una función de prueba. Supongamos que tengo 5 funciones de prueba y 5 clases que quiero probar. Esto haría 25 funciones que parecen casi idénticas para invocar todas las pruebas.

Otro enfoque en el que estaba pensando era implementar la plantilla como una superclase y luego crear una subclase para cada una de las clases que quiero probar. Las subclases podrían proporcionar una función para instanciar la clase. El problema con eso es que el cargador de prueba predeterminado consideraría la clase base (inutilizable) como un caso de prueba válido e intentaría ejecutarlo, lo que fallaría.

Entonces, ¿cuáles son tus sugerencias?

PD: estoy usando Python 2.6

Podrías usar herencia múltiple.

 class PartitionerInvariantsFixture(object): def setUp(self): self.testDataSet = range(100) # create test-data-set super(PartitionInvariantsFixture, self).setUp() def test_partitioner(self): TestCase.assertEqual(self.testDataSet, chain.from_iterable(self.partitioner(self.testDataSet)) class MyClassTests(TestCase, PartitionerInvariantsFixture): partitioner = Partitioner 

Subclase PartitionerInvariantsTests :

 class PartitionerInvariantsTests(unittest.TestCase): def test_impl(self): self.assertEqual(self.testDataSet, chain.from_iterable(self.partitioner(self.testDataSet)) class PartitionerATests(PartitionerInvariantsTests): 

para cada clase de Partitioner que desee probar. Luego, test_impl se ejecutaría para cada clase de Partitioner, en virtud de la herencia.

Siguiendo el comentario de Nathon, puedes evitar que la clase base sea probada haciéndola heredar solo del object :

 import unittest class Test(object): def test_impl(self): print('Hi') class TestA(Test,unittest.TestCase): pass class TestB(Test,unittest.TestCase): pass if __name__ == '__main__': unittest.sys.argv.insert(1,'--verbose') unittest.main(argv = unittest.sys.argv) 

Ejecutando test.py rendimientos

 test_impl (__main__.TestA) ... Hi ok test_impl (__main__.TestB) ... Hi ok ---------------------------------------------------------------------- Ran 2 tests in 0.000s OK