Ich habe derzeit einige Unit-Tests, die eine gemeinsame Reihe von Tests teilen. Hier ist ein Beispiel:
import unittest
class BaseTest(unittest.TestCase):
def testCommon(self):
print 'Calling BaseTest:testCommon'
value = 5
self.assertEquals(value, 5)
class SubTest1(BaseTest):
def testSub1(self):
print 'Calling SubTest1:testSub1'
sub = 3
self.assertEquals(sub, 3)
class SubTest2(BaseTest):
def testSub2(self):
print 'Calling SubTest2:testSub2'
sub = 4
self.assertEquals(sub, 4)
if __name__ == '__main__':
unittest.main()
Die Ausgabe der oben genannten ist:
Calling BaseTest:testCommon
.Calling BaseTest:testCommon
.Calling SubTest1:testSub1
.Calling BaseTest:testCommon
.Calling SubTest2:testSub2
.
----------------------------------------------------------------------
Ran 5 tests in 0.000s
OK
Gibt es eine Möglichkeit, das Obige so umzuschreiben, dass das allererste testCommon
nicht aufgerufen wird?
BEARBEITEN: Anstatt 5 Tests oben auszuführen, möchte ich, dass nur 4 Tests ausgeführt werden, 2 vom SubTest1 und weitere 2 vom SubTest2. Es scheint, dass Python unittest den ursprünglichen BaseTest alleine ausführt, und ich brauche einen Mechanismus, um dies zu verhindern.
python
unit-testing
testing
Thierry Lam
quelle
quelle
Antworten:
Verwenden Sie die Mehrfachvererbung, damit Ihre Klasse mit allgemeinen Tests nicht selbst von TestCase erbt.
quelle
setUp
und sie für jeden Test in abgeleiteten Klassen aufrufen möchten, müssen Sie die Reihenfolge der Basisklassen umkehren. so dass es sein wird : .tearDown
CommonTests
class SubTest1(CommonTests, unittest.TestCase)
unittest.TestCase
und erben müssenCommonTests
. Ich denke, die folgendesetUpClass
Methode ist die beste und weniger anfällig für menschliches Versagen. Entweder das oder das Umschließen der BaseTest-Klasse in eine Containerklasse, die etwas hackiger ist, aber die Überspringmeldung im Ausdruck des Testlaufs vermeidet.CommonTests
es Methoden aufruft, die in dieser Klasse nicht existieren.Verwenden Sie keine Mehrfachvererbung, sie wird Sie später beißen .
Stattdessen können Sie Ihre Basisklasse einfach in das separate Modul verschieben oder mit der leeren Klasse umschließen:
Die Ausgabe:
quelle
Sie können dieses Problem mit einem einzigen Befehl lösen:
Der Code würde also so aussehen:
quelle
self.assert*
Methoden in einem Standardobjekt nicht vorhanden sind.super( BaseTest, cls ).setUpClass( )
BaseTest
kann durchsuper(self.__class__, self)
oder nursuper()
in den Unterklassen verwiesen werden , obwohl dies anscheinend nicht der Fall ist , wenn Sie Konstruktoren erben würden . Vielleicht gibt es auch eine solche "anonyme" Alternative, wenn die Basisklasse sich selbst referenzieren muss (nicht, dass ich eine Idee habe, wenn eine Klasse sich selbst referenzieren muss).Die Antwort von Matthew Marshall ist großartig, erfordert jedoch, dass Sie in jedem Ihrer Testfälle von zwei Klassen erben, was fehleranfällig ist. Stattdessen benutze ich dies (Python> = 2.7):
quelle
Was versuchst du zu erreichen? Wenn Sie allgemeinen Testcode haben (Zusicherungen, Vorlagentests usw.), platzieren Sie diese in Methoden, denen kein Präfix vorangestellt ist,
test
damitunittest
sie nicht geladen werden.quelle
Matthews Antwort ist die, die ich verwenden musste, da ich immer noch auf 2.5 bin. Ab 2.7 können Sie den Dekorator @ unittest.skip () für alle Testmethoden verwenden, die Sie überspringen möchten.
http://docs.python.org/library/unittest.html#skipping-tests-and-expected-failures
Sie müssen Ihren eigenen überspringenden Dekorateur implementieren, um den Basistyp zu überprüfen. Haben Sie diese Funktion nicht vor verwendet, aber aus der Spitze von meinem Kopf konnte man BaseTest als verwendet Marker Art den Sprung zu konditionieren:
quelle
Eine Möglichkeit, dies zu lösen, besteht darin, die Testmethoden auszublenden, wenn die Basisklasse verwendet wird. Auf diese Weise werden die Tests nicht übersprungen, sodass die Testergebnisse in vielen Testberichtstools grün statt gelb sein können.
Im Vergleich zur Mixin-Methode beklagen sich Ideen wie PyCharm nicht darüber, dass Unit-Test-Methoden in der Basisklasse fehlen.
Wenn eine Basisklasse von dieser Klasse erbt, muss sie die Methoden
setUpClass
und überschreibentearDownClass
.quelle
Sie können die
__test_ = False
BaseTest-Klasse hinzufügen. Wenn Sie sie jedoch hinzufügen, müssen Sie__test__ = True
abgeleitete Klassen hinzufügen , um Tests ausführen zu können.quelle
Eine andere Option ist nicht auszuführen
Stattdessen können Sie verwenden
Sie führen also nur die Tests in der Klasse aus
TestClass
quelle
unittest.main()
in der Standardsuite erfasst wird, bilden Sie eine explizite Suite und führen deren Tests aus.Ich habe ungefähr das Gleiche gemacht wie @Vladim P. ( https://stackoverflow.com/a/25695512/2451329 ), aber leicht modifiziert:
und los geht's.
quelle
Ab Python 3.2 können Sie einem Modul eine test_loader- Funktion hinzufügen, um zu steuern, welche Tests (falls vorhanden) vom Testerkennungsmechanismus gefunden werden.
Im Folgenden werden beispielsweise nur die Originalposter
SubTest1
undSubTest2
Testfälle geladen, wobei Folgendes ignoriert wirdBase
:Es sollte möglich sein , iterieren
standard_tests
(aTestSuite
und kopieren Sie alle Tests der Standard - loader Enthalten gefunden) , aberBase
zusuite
statt, aber die verschachtelte NaturTestSuite.__iter__
macht , dass viel mehr kompliziert.quelle
Benennen Sie die testCommon-Methode einfach in etwas anderes um. Unittest überspringt (normalerweise) alles, was keinen "Test" enthält.
Schnell und einfach
quelle
Das ist also eine Art alter Thread, aber ich bin heute auf dieses Problem gestoßen und habe mir meinen eigenen Hack dafür ausgedacht. Es wird ein Dekorator verwendet, der die Werte der Funktionen None festlegt, wenn er über die Basisklasse aufgerufen wird. Sie müssen sich keine Gedanken über Setup und Setup-Klasse machen, denn wenn die Basisklasse keine Tests enthält, werden sie nicht ausgeführt.
quelle
Ändern Sie den Namen der BaseTest-Methode in setUp:
Ausgabe:
Aus der Dokumentation :
quelle
setUp
?test...
Methode hat,setUp
wird sie immer wieder ausgeführt, einmal pro solcher Methode. Es ist also keine gute Idee, dort Tests durchzuführen!