Wie kann man einen Fehler in einem Python-Komponententest in der Methode setUp korrekt melden?

8

Ich habe einige widersprüchliche Hinweise zur Verwendung von assert in der Methode setUp eines Python-Komponententests gelesen. Ich kann den Schaden nicht sehen, der einen Test versagt, wenn eine Vorbedingung, die auf Test beruht, ausfällt.

Zum Beispiel:

%Vor%

Das scheint mir eine vernünftige Sache zu sein, d. h. ich stelle sicher, dass der Test ausgeführt werden kann. Wenn dies aufgrund der Setup-Bedingung fehlschlägt, erhalten wir:

%Vor%     
Jon Cage 10.05.2016, 09:24
quelle

5 Antworten

9

Der Zweck von setUp ist es, den Boilerplate-Code zu reduzieren, der beim Arrange zwischen den Tests in der Testklasse entsteht Phase.

In der Arrange-Phase müssen Sie: alles einrichten, was für die Ausführung des getesteten Codes benötigt wird. Dies beinhaltet jegliche Initialisierung von Abhängigkeiten, Mocks und Daten, die für den Test benötigt werden.

Basierend auf den obigen Absätzen sollten Sie nichts in Ihrer setUp -Methode angeben.

Wie bereits erwähnt; Wenn Sie die Testvoraussetzung nicht erstellen können, ist Ihr Test abgebrochen. Um solche Situationen zu vermeiden, schrieb Roy Osherove ein großartiges Buch mit dem Titel: Die Kunst der Unit Testing (Für eine vollständige Offenlegung ist Lior Friedman (Er war Roy's Chef) ein Freund von mir und ich arbeitete eng mit ihnen seit mehr als 2 Jahren, also bin ich klein Bit voreingenommen ...)

Grundsätzlich gibt es nur wenige Gründe für eine Interaktion mit externen Ressourcen während der Arrangierphase (oder mit Dingen, die eine Ausnahme verursachen können), die meisten von ihnen (wenn nicht alle) sind in Integrationstests verwandt.

Zurück zu Ihrem Beispiel; Es gibt ein Muster, um die Tests zu strukturieren Sie müssen eine externe Ressource laden (für alle / die meisten von ihnen). Nur eine Randnotiz; Bevor Sie sich entscheiden, dieses Muster anzuwenden, stellen Sie sicher, dass Sie diesen Inhalt nicht als statische Ressource in Ihrer UT-Klasse verwenden können, wenn andere Testklassen diese Ressource verwenden müssen, um diese Ressource in ein Modul zu extrahieren.

Das folgende Muster verringert die Wahrscheinlichkeit eines Fehlers, da Sie weniger Aufrufe an die externe Ressource haben:

%Vor%

Pros:

  1. weniger Chancen zum Scheitern
  2. verhindert Inkonsistenzverhalten (1. etwas / jemand hat die externe Ressource bearbeitet. 2. Sie konnten die externe Ressource in einigen Ihrer Tests nicht laden)
  3. schnellere Ausführung

Nachteile:

  1. Der Code ist komplexer
Old Fox 22.05.2016, 13:23
quelle
5

setUp dient nicht zum Bestätigen , sondern zum Erstellen . Wenn Ihr Test das erforderliche Fixture nicht erstellen kann, ist es defekt und nicht fehlerhaft.

    
user5547025 10.05.2016 09:27
quelle
3

Aus der Python-Standardbibliotheksdokumentation :

"Wenn die Methode setUp () während des Tests eine Ausnahme auslöst, das Framework wird den Test für einen Fehler halten, und Die Methode runTest () wird nicht ausgeführt. Wenn setUp () erfolgreich war, Die Methode trineDown () wird ausgeführt, unabhängig davon, ob runTest () erfolgreich war oder nicht. Eine solche Eine Arbeitsumgebung für den Testcode wird Fixture genannt. "

Eine Assertion-Ausnahme in der setUp () -Methode würde vom Unittest-Framework als Fehler angesehen werden. Der Test wird nicht ausgeführt.

    
user3271619 20.05.2016 15:41
quelle
2

Hier gibt es keine richtige oder falsche Antwort, es kommt darauf an, was Sie testen und wie teuer Ihre Tests sind. Einige Tests sind zu gefährlich, um versuchte Läufe zuzulassen, wenn die Daten nicht wie erwartet sind, einige müssen mit diesen Daten arbeiten.

Sie können Assertionen in setUp verwenden, wenn Sie zwischen Tests auf bestimmte Bedingungen prüfen müssen. Dies kann dazu beitragen, wiederholten Code in Ihren Tests zu reduzieren. Es macht jedoch auch bewegende Testmethoden zwischen Klassen oder Dateien ein wenig komplizierter, da sie auf das äquivalente setUp angewiesen sind. Es kann auch die Grenzen der Komplexität für weniger Code-versierte Tester verschieben.

Es ist ein bisschen sauberer, einen Test zu haben, der diese Startbedingungen einzeln überprüft und sie zuerst ausführt, sie werden zwischen den einzelnen Tests möglicherweise nicht benötigt. Wenn Sie es als test_01_check_preconditions definieren, wird es vor allen anderen Testmethoden ausgeführt, auch wenn der Rest zufällig ist. Sie können dann auch unittest2.skip-Dekoratoren für bestimmte Bedingungen verwenden.

Ein besserer Ansatz ist die Verwendung von addCleanup, um sicherzustellen, dass der Status zurückgesetzt wird. Der Vorteil hierbei ist, dass selbst bei fehlgeschlagenem Test die Bereinigung besser auf die spezifische Situation aufmerksam wird, wenn Sie sie definieren Kontext Ihrer Testmethode.

Es gibt auch nichts, was Sie davon abhält, Methoden zu definieren, um allgemeine Prüfungen in der unittest-Klasse durchzuführen und sie in setUp oder in test_methods aufzurufen, dies kann dazu beitragen, Komplexität in definierten und verwalteten Bereichen zu halten.

Seien Sie auch nicht versucht, unittest2 über eine einfache Testdefinition hinaus zu untergliedern. Ich habe gesehen, dass Leute versuchen, das zu tun, um Tests einfach zu machen und tatsächlich völlig unerwartetes Verhalten einzuführen.

Ich nehme an, der wahre Nachhauseweg ist, wenn Sie es wissen, warum Sie es verwenden und sicherstellen möchten, dass Sie Ihre Gründe dokumentieren, ist es wahrscheinlich in Ordnung, wenn Sie sich nicht sicher sind, dann gehen Sie für die einfachste leicht zu verstehen Option, weil Tests nutzlos sind wenn sie nicht leicht zu verstehen sind.

    
Amias 18.05.2016 12:10
quelle
2

Es gibt einen Grund, warum Sie Assertionen in setUp() vermeiden möchten. Wenn setUp fehlschlägt, wird Ihr tearDown nicht ausgeführt.

Wenn Sie zum Beispiel eine Reihe von Datenbankeinträgen einrichten und Ihre Teardown diese Datensätze löscht, werden diese Datensätze nicht gelöscht.

Mit diesem Snippet:

%Vor%

Sie führen nur das setUp() :

aus %Vor%     
Philippe Ombredanne 23.05.2016 07:56
quelle