In Pythons Unittest fortfahren, wenn eine Assertion fehlschlägt
EDIT: geschaltet, um ein besseres Beispiel zu geben, und geklärt ist, warum das ist ein echtes problem.
Möchte ich schreiben von unit-tests in Python, die weiterhin ausgeführt werden, wenn eine assertion fehlschlägt, so dass ich sehen kann, mehrere Fehler in einem einzigen test. Zum Beispiel:
class Car(object):
def __init__(self, make, model):
self.make = make
self.model = make # Copy and paste error: should be model.
self.has_seats = True
self.wheel_count = 3 # Typo: should be 4.
class CarTest(unittest.TestCase):
def test_init(self):
make = "Ford"
model = "Model T"
car = Car(make=make, model=model)
self.assertEqual(car.make, make)
self.assertEqual(car.model, model) # Failure!
self.assertTrue(car.has_seats)
self.assertEqual(car.wheel_count, 4) # Failure!
Hier, der Zweck des Tests ist es sicherzustellen, dass Auto __init__
setzt seine Felder korrekt. Ich könnte brechen Sie in vier Methoden (und das ist oft eine gute Idee), aber in diesem Fall denke ich ist es besser lesbar zu halten, als eine einzelne Methode, dass die tests auf einem einzigen Konzept ("das Objekt korrekt initialisiert").
Wenn wir davon ausgehen, dass es hier am besten, um nicht zu brechen, bis Sie die Methode, dann habe ich ein neues problem: ich kann nicht sehen, alle Fehler auf einmal. Wenn ich fix die model
Fehler und starten den test erneut, dann ist die wheel_count
Fehler angezeigt. Es wäre sparen Sie Zeit hat mich zu sehen, dass beide Fehler, wenn ich zuerst den test ausführen.
Zum Vergleich, Google C++ unit-Test framework unterscheidet zwischen zwischen nicht-tödlichen EXPECT_*
Behauptungen und tödlich ASSERT_*
Behauptungen:
Die Behauptungen kommen in Paaren, testen Sie die gleiche Sache, aber haben unterschiedliche Auswirkungen auf die aktuelle Funktion. ASSERT_* Versionen erzeugen fatalen Fehler, wenn Sie scheitern und Abbruch der aktuellen Funktion. EXPECT_* Versionen erzeugen nicht schwerwiegende Fehler, die nicht zum Abbruch der aktuellen Funktion. In der Regel EXPECT_* werden bevorzugt, da Sie es erlauben, mehr als einen Fehler gemeldet werden, die in einem test. Sie sollten jedoch ASSERT_* wenn es keinen Sinn macht weiter zu machen, wenn die Behauptung in Frage, schlägt fehl.
Gibt es einen Weg, um EXPECT_*
-wie Verhalten in Python unittest
? Wenn nicht in unittest
, dann ist es eine andere Python-unit-test-framework unterstützt dieses Verhalten?
Übrigens, ich war neugierig, wie viele real-life-tests profitieren könnten, von nicht-tödlichen Behauptungen, also schaute ich einige code-Beispiele (bearbeitet 2014-08-19 zu verwenden searchcode statt der Google-Code-Suche, RIP). Von 10 zufällig ausgewählte Ergebnisse aus der ersten Seite, alle enthaltenen Prüfungen, die aus mehreren unabhängigen Aussagen in die gleiche test Methode. Alle würden profitieren von nicht-fatalen Behauptungen.
InformationsquelleAutor der Frage Bruce Christensen | 2011-01-19
Du musst angemeldet sein, um einen Kommentar abzugeben.
Was Sie wahrscheinlich tun möchten, ist abzuleiten
unittest.TestCase
da, das ist die Klasse, wirft, wenn eine assertion fehlschlägt. Sie müssen re-Architekt IhreTestCase
nicht zu werfen (vielleicht halten Sie eine Liste von Fehlern statt). Re-architecting Sachen können dazu führen, dass andere Probleme, die Sie hätten, zu beheben. Zum Beispiel können Sie am Ende brauchen, um abzuleitenTestSuite
änderungen support-änderungen an IhremTestCase
.InformationsquelleAutor der Antwort dietbuddha
Anderen Weg, um nicht-schwerwiegende Behauptungen ist das erfassen der Geltendmachung Ausnahme, und speichern Sie die Ausnahmen in einer Liste. Dann behaupten, dass diese Liste leer ist als Teil der ZERLEGUNG.
InformationsquelleAutor der Antwort Anthony Batchelor
Eine Möglichkeit ist, die geltend machen, auf der alle Werte auf einmal als ein Tupel.
Beispiel:
Die Ausgabe dieses tests:
Dies zeigt, dass sowohl das Modell und das Rad zu zählen sind falsch.
InformationsquelleAutor der Antwort hwiechers
Es wird als ein anti-pattern, das mehrere asserts in einem einzigen unit-test. Eine single-unit-test wird erwartet, dass der test nur eins. Vielleicht sind Sie testen zu viel. Aufteilen dieser test in mehreren tests. Auf diese Weise können Sie den Namen jeder richtig testen.
Manchmal jedoch, es in Ordnung ist, überprüfen Sie mehrere Dinge zur gleichen Zeit. Zum Beispiel, wenn Sie die Geltendmachung von Eigenschaften des gleichen Objekts. In diesem Fall sind Sie in der Tat behaupten, ob das Objekt korrekt ist. Ein Weg, dies zu tun ist, schreiben Sie eine benutzerdefinierte helper-Methode, die weiß, wie zu behaupten, die auf diesem Objekt. Sie können schreiben, dass die Methode in einer solchen Weise, dass es zeigt alle fehlerhaften Eigenschaften oder zum Beispiel zeigt den vollständigen Zustand der erwarteten Objekt und den vollständigen Zustand des eigentlichen Objekts, wenn eine Assertion fehlschlägt.
InformationsquelleAutor der Antwort Steven
Kann jeder behaupten, in einem separaten Verfahren.
InformationsquelleAutor der Antwort Lennart Regebro
Ich mochte den Ansatz von @Anthony-Batchelor, zu erfassen, die AssertionError-Ausnahme. Aber eine leichte variation dieses Ansatzes mit Hilfe von Dekoratoren und auch ein Weg, Bericht zu den tests Fälle mit pass/fail.
Ausgabe von der Konsole:
InformationsquelleAutor der Antwort Zoro_77
erwarten, ist sehr nützlich, in gtest.
Ist diese python-Art in gist, und code:
InformationsquelleAutor der Antwort Ken
Ich glaube nicht, dass es einen Weg gibt, dies zu tun mit PyUnit und würde nicht wollen, um zu sehen, PyUnit verlängert auf diese Weise.
Ich bleibe lieber auf eine assertion pro test-Funktion (oder genauer gesagt die Durchsetzung Konzept pro test) und würde umzuschreiben
test_addition()
als vier separate test-Funktionen. Dies würde es erlauben, mehr nützliche Informationen über Fehler, viz:Wenn Sie entscheiden, dass dieser Ansatz nicht für Sie, können Sie finden diese Antwort hilfreich.
Update
Es sieht aus wie Sie sind, testen die beiden Konzepte mit Ihren aktualisierten Frage-und ich würde teilen diese in zwei unit-tests. Die erste ist, dass die Parameter gespeichert sind, die auf die Schaffung eines neuen Objekts. Dies hätte zwei Aussagen, eine für
make
und eine fürmodel
. Wenn der erste ausfällt, der das deutlich repariert werden muss, ob der zweite Test besteht oder nicht besteht, ist irrelevant an dieser Stelle.Das zweite Konzept ist eher fraglich... Man testen, ob einige default-Werten initialisiert werden. Warum? Es wäre nützlicher, um zu testen, diese Werte an dem Punkt, dass Sie tatsächlich verwendet werden (und wenn Sie nicht gewohnt sind, warum sind Sie dann da?).
Beide diese tests fehlschlagen, und beide sollten. Wenn ich unit-Tests, ich bin weit mehr daran interessiert, in der Fehler als ich in den Erfolg, wie das ist, wo ich brauche zu konzentrieren.
InformationsquelleAutor der Antwort Johnsyweb