Wenn ich Unit-Tests in Python schreibe (mit dem unittest-Modul), ist es dann möglich, Daten aus einem fehlgeschlagenen Test auszugeben, damit ich sie untersuchen kann, um herauszufinden, was den Fehler verursacht hat? Ich bin mir der Möglichkeit bewusst, eine benutzerdefinierte Nachricht zu erstellen, die einige Informationen enthalten kann, aber manchmal können Sie mit komplexeren Daten umgehen, die nicht einfach als Zeichenfolge dargestellt werden können.
Angenommen, Sie hatten eine Klasse Foo und testeten eine Methodenleiste mit Daten aus einer Liste namens testdata:
class TestBar(unittest.TestCase):
def runTest(self):
for t1, t2 in testdata:
f = Foo(t1)
self.assertEqual(f.bar(t2), 2)
Wenn der Test fehlgeschlagen ist, möchte ich möglicherweise t1, t2 und / oder f ausgeben, um festzustellen, warum diese bestimmten Daten zu einem Fehler geführt haben. Mit Ausgabe meine ich, dass auf die Variablen wie auf alle anderen Variablen zugegriffen werden kann, nachdem der Test ausgeführt wurde.
quelle
msg
ist jedoch ausdrücklich zu erwähnen: Wenn diese Option verwendet wird, wird standardmäßig die normale Fehlermeldung ersetzt. Ummsg
an die normale Fehlermeldung angehängt zu werden, müssen Sie auch TestCase.longMessage auf True setzenTrue
.Wir verwenden dafür das Protokollierungsmodul.
Beispielsweise:
Auf diese Weise können wir das Debuggen für bestimmte Tests aktivieren, von denen wir wissen, dass sie fehlschlagen und für die wir zusätzliche Debugging-Informationen benötigen.
Meine bevorzugte Methode ist jedoch nicht, viel Zeit mit dem Debuggen zu verbringen, sondern feinere Tests zu schreiben, um das Problem aufzudecken.
quelle
foo
? Eine separate Funktion? Eine Methodenfunktion vonSomeTest
? Im ersten Fall kann eine Funktion einen eigenen Logger haben. Im zweiten Fall kann die andere Methodenfunktion einen eigenen Logger haben. Wissen Sie, wie daslogging
Paket funktioniert? Mehrere Logger sind die Norm.Sie können einfache Druckanweisungen oder eine andere Schreibweise für stdout verwenden. Sie können den Python-Debugger auch an einer beliebigen Stelle in Ihren Tests aufrufen.
Wenn Sie Ihre Tests mit der Nase ausführen (was ich empfehle), wird die Standardausgabe für jeden Test erfasst und nur angezeigt, wenn der Test fehlgeschlagen ist, sodass Sie beim Bestehen der Tests nicht mit der überfüllten Ausgabe leben müssen.
Nase hat auch Schalter, um die in Asserts erwähnten Variablen automatisch anzuzeigen oder den Debugger bei fehlgeschlagenen Tests aufzurufen. Zum Beispiel
-s
(--nocapture
) verhindert die Erfassung von stdout.quelle
print
undlog.debug()
nebeneinander und aktiviere explizit dieDEBUG
Protokollierung im Stammverzeichnis dersetUp()
Methode, aber nur dieprint
Ausgabe wird angezeigt.nosetests -s
zeigt den Inhalt von stdout, ob ein Fehler vorliegt oder nicht - etwas, das ich nützlich finde.Ich denke nicht, dass dies genau das ist, wonach Sie suchen. Es gibt keine Möglichkeit, Variablenwerte anzuzeigen, die nicht fehlschlagen. Dies kann Ihnen jedoch dabei helfen, die Ausgabe der gewünschten Ergebnisse näher zu bringen.
Sie können das von TestRunner.run () zurückgegebene TestResult-Objekt zur Ergebnisanalyse und -verarbeitung verwenden. Insbesondere TestResult.errors und TestResult.failures
Informationen zum TestResults-Objekt:
http://docs.python.org/library/unittest.html#id3
Und ein Code, der Sie in die richtige Richtung weist:
quelle
Eine weitere Option: Starten Sie einen Debugger, bei dem der Test fehlschlägt.
Versuchen Sie, Ihre Tests mit Testoob auszuführen (es wird Ihre unittest Suite ohne Änderungen ausführen), und Sie können den Befehlszeilenschalter '--debug' verwenden, um einen Debugger zu öffnen, wenn ein Test fehlschlägt.
Hier ist eine Terminalsitzung unter Windows:
quelle
Die Methode, die ich benutze, ist wirklich einfach. Ich protokolliere es nur als Warnung, damit es tatsächlich angezeigt wird.
quelle
Ich glaube, ich hätte das überlegt. Eine Möglichkeit, die ich mir ausgedacht habe, besteht darin, einfach eine globale Variable zu haben, die die Diagnosedaten sammelt.
So etwas in der Art:
Danke für die Antworten. Sie haben mir einige alternative Ideen gegeben, wie man Informationen aus Unit-Tests in Python aufzeichnet.
quelle
Protokollierung verwenden:
Verwendung:
Wenn Sie nicht festlegen
LOG_FILE
, wird die Protokollierung durchgeführtstderr
.quelle
Sie können das
logging
Modul dafür verwenden.Verwenden Sie also im Unit-Test-Code:
Standardmäßig werden Warnungen und Fehler ausgegeben
/dev/stderr
, sodass sie auf der Konsole sichtbar sein sollten.Versuchen Sie das folgende Beispiel, um Protokolle anzupassen (z. B. die Formatierung):
quelle
Was ich in diesen Fällen mache, ist eine
log.debug()
mit einigen Nachrichten in meiner Anwendung zu haben. Da die Standardprotokollierungsstufe istWARNING
, werden solche Nachrichten in der normalen Ausführung nicht angezeigt .Dann ändere ich im Unittest die Protokollierungsstufe auf
DEBUG
, so dass solche Nachrichten angezeigt werden, während sie ausgeführt werden.In den Unittests:
Ein vollständiges Beispiel anzeigen:
Dies ist
daikiri.py
eine Grundklasse, die einen Daikiri mit seinem Namen und Preis implementiert. Es gibt eine Methodemake_discount()
, die den Preis dieses bestimmten Daikiri nach Anwendung eines bestimmten Rabatts zurückgibt:Dann erstelle ich ein Unittest
test_daikiri.py
, das seine Verwendung überprüft:Wenn ich es ausführe, erhalte ich folgende
log.debug
Meldungen:quelle
Mit inspect.trace können Sie lokale Variablen abrufen, nachdem eine Ausnahme ausgelöst wurde. Anschließend können Sie die Komponententests mit einem Dekorateur wie dem folgenden abschließen, um diese lokalen Variablen für die Untersuchung während der Obduktion zu speichern.
In der letzten Zeile werden die zurückgegebenen Werte gedruckt, bei denen der Test erfolgreich war, und die lokalen Variablen, in diesem Fall x, wenn dies fehlschlägt:
Har det gøy :-)
quelle
Wie wäre es, wenn Sie die Ausnahme abfangen, die durch den Assertionsfehler generiert wird? In Ihrem catch-Block können Sie die Daten nach Belieben ausgeben, wo immer Sie möchten. Wenn Sie fertig sind, können Sie die Ausnahme erneut auslösen. Der Testläufer würde den Unterschied wahrscheinlich nicht kennen.
Haftungsausschluss: Ich habe dies nicht mit dem Unit-Test-Framework von Python versucht, sondern mit anderen Unit-Test-Frameworks.
quelle
Zugegeben, ich habe es nicht ausprobiert, die Protokollierungsfunktion der Testgeräte sieht sehr nützlich aus ...
quelle
Wenn ich die Antwort von @FC erweitere, funktioniert das ganz gut für mich:
quelle