Wenn Sie wirklich mehrere Einheiten haben möchten, dann brauchen Sie mehrere Methoden. Der einzige Weg, um das zu erreichen, ist durch eine Art Code-Generierung. Sie können dies über Metaklassen tun, oder indem Sie die Klasse nach der Definition optimieren, einschließlich (wenn Sie Python 2.6 verwenden) über einen Klassendekorator.
Hier ist eine Lösung, die nach den speziellen 'multititest' und 'multitest_values' Mitgliedern sucht und diese verwendet, um die Testmethoden on the fly zu erstellen. Nicht elegant, aber es hat in etwa, was Sie wollen:
import unittest
import inspect
class SomeValue(object):
def __eq__(self, other):
return other in [1, 3, 4]
class ExampleTestCase(unittest.TestCase):
somevalue = SomeValue()
multitest_values = [1, 2, 3, 4]
def multitest(self, n):
self.assertEqual(self.somevalue, n)
multitest_gt_values = "ABCDEF"
def multitest_gt(self, c):
self.assertTrue(c > "B", c)
def add_test_cases(cls):
values = {}
functions = {}
# Find all the 'multitest*' functions and
# matching list of test values.
for key, value in inspect.getmembers(cls):
if key.startswith("multitest"):
if key.endswith("_values"):
values[key[:-7]] = value
else:
functions[key] = value
# Put them together to make a list of new test functions.
# One test function for each value
for key in functions:
if key in values:
function = functions[key]
for i, value in enumerate(values[key]):
def test_function(self, function=function, value=value):
function(self, value)
name ="test%s_%d" % (key[9:], i+1)
test_function.__name__ = name
setattr(cls, name, test_function)
add_test_cases(ExampleTestCase)
if __name__ == "__main__":
unittest.main()
Dies ist die Ausgabe aus, wenn ich es laufen
% python stackoverflow.py
.F..FF....
======================================================================
FAIL: test_2 (__main__.ExampleTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
File "stackoverflow.py", line 34, in test_function
function(self, value)
File "stackoverflow.py", line 13, in multitest
self.assertEqual(self.somevalue, n)
AssertionError: <__main__.SomeValue object at 0xd9870> != 2
======================================================================
FAIL: test_gt_1 (__main__.ExampleTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
File "stackoverflow.py", line 34, in test_function
function(self, value)
File "stackoverflow.py", line 17, in multitest_gt
self.assertTrue(c > "B", c)
AssertionError: A
======================================================================
FAIL: test_gt_2 (__main__.ExampleTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
File "stackoverflow.py", line 34, in test_function
function(self, value)
File "stackoverflow.py", line 17, in multitest_gt
self.assertTrue(c > "B", c)
AssertionError: B
----------------------------------------------------------------------
Ran 10 tests in 0.001s
FAILED (failures=3)
Sie sofort einige der Probleme sehen, die mit Code-Generierung auftreten. Woher kommt "test_gt_1"? Ich könnte den Namen in den längeren "test_multitest_gt_1" ändern, aber welcher Test ist dann 1? Besser wäre es, von _0 statt von _1 zu starten, und vielleicht wissen Sie in Ihrem Fall, dass die Werte als Python-Funktionsname verwendet werden können.
Ich mag diesen Ansatz nicht. Ich habe an Code-Basen gearbeitet, die automatisch Testmethoden entwickelten (in einem Fall mit einer Metaklasse) und festgestellt, dass es viel schwieriger zu verstehen war, als es nützlich war. Wenn ein Test fehlschlug, war es schwierig, die Quelle des Fehlerfalls herauszufinden, und es war schwierig, den Debugging-Code beizubehalten, um nach dem Grund für den Fehler zu suchen.
(Debugging-Fehler in dem Beispiel, das ich hier geschrieben habe, ist nicht so schwer wie der spezifische Metaklassen-Ansatz, mit dem ich arbeiten musste.)
Haben Sie einen Weg finden, dies zu tun? Oder haben Sie vielleicht ein anderes Werkzeug für diese Aufgabe gefunden? Ich brauche auch solches Verhalten. – legesh
http://thebongtraveller.blogspot.sg/2015/12/art-of-unittest-writing-auto-generation.html Ist das die gleiche Sache? –