Ich schreibe Tests für ein Projekt, das aus mehreren Submodulen besteht. Jeder Testfall, den ich geschrieben habe, läuft unabhängig voneinander und ich lösche alle Daten zwischen den Tests.
Obwohl die Tests unabhängig voneinander ausgeführt werden, erwäge ich, eine Ausführungsreihenfolge durchzusetzen, da in einigen Fällen mehr als ein Submodul erforderlich ist. Beispielsweise generiert ein Submodul Daten, und ein anderes Submodul führt Abfragen für die Daten aus. Wenn das Submodul, das die Daten generiert, einen Fehler enthält, schlägt auch der Test für das Abfragesubmodul fehl, selbst wenn das Submodul selbst einwandfrei funktioniert.
Ich kann nicht mit Dummy-Daten arbeiten, da die Hauptfunktion, die ich teste, die Verbindung zu einem Black-Box-Remote-Server ist, der nur die Daten vom ersten Submodul abruft.
Ist es in diesem Fall in Ordnung, eine Ausführungsreihenfolge für die Tests durchzusetzen, oder handelt es sich um eine falsche Vorgehensweise? Ich habe das Gefühl, dass es in diesem Setup einen Geruch gibt, aber ich kann keinen besseren Weg finden.
Bearbeiten: Die Frage lautet: Wie werden Tests strukturiert, bei denen ein Test der Aufbau eines anderen Tests ist? da der "vorherige" Test kein Setup ist, sondern den Code testet, der das Setup durchführt.
quelle
Antworten:
Dies ist der Schlüssel für mich. Sie können von "Komponententests" und "unabhängig voneinander laufen" sprechen, aber sie klingen alle so, als wären sie auf diesen Remote-Server und auf das "erste Submodul" angewiesen. Es klingt also alles eng gekoppelt und abhängig vom äußeren Zustand. Als solches schreiben Sie tatsächlich Integrationstests. Es ist ganz normal, dass diese Tests in einer bestimmten Reihenfolge ausgeführt werden, da sie stark von externen Faktoren abhängen. Ein bestellter Testlauf mit der Möglichkeit, den Testlauf vorzeitig abzubrechen, falls etwas schief geht, ist für Integrationstests durchaus akzeptabel.
Es lohnt sich aber auch, einen Blick auf die Struktur Ihrer App zu werfen. Wenn Sie in der Lage sind, das erste Submodul und den externen Server zu verspotten, können Sie möglicherweise echte Komponententests für alle anderen Submodule schreiben.
quelle
Ja, es ist eine schlechte Praxis.
Im Allgemeinen soll ein Komponententest eine einzelne Codeeinheit testen (z. B. eine einzelne Funktion basierend auf einem bekannten Zustand).
Wenn Sie eine Kette von Ereignissen testen möchten, die in der Natur auftreten können, möchten Sie einen anderen Teststil, z. B. einen Integrationstest. Dies gilt umso mehr, wenn Sie von einem Drittanbieter abhängig sind.
Um solche Dinge einem Komponententest zu unterziehen, müssen Sie eine Möglichkeit zum Einfügen der Dummy-Daten finden, beispielsweise eine Datendienstschnittstelle implementieren, die die Webanforderung spiegelt, jedoch bekannte Daten aus einer lokalen Dummy-Datendatei zurückgibt.
quelle
Die von Ihnen vorgeschlagene erzwungene Ausführungsreihenfolge ist nur dann sinnvoll, wenn Sie den Testlauf auch nach dem ersten Fehler abbrechen.
Der Abbruch des Testlaufs bei dem ersten Fehler bedeutet, dass jeder Testlauf nur ein einziges Problem aufdecken kann und keine neuen Probleme finden kann, bis alle vorhergehenden Probleme behoben wurden. Wenn der erste ausgeführte Test ein Problem feststellt, dessen Behebung einen Monat in Anspruch nimmt, werden in diesem Monat effektiv keine Tests ausgeführt.
Wenn Sie den Testlauf bei dem ersten Fehler nicht abbrechen, bringt Ihnen die erzwungene Ausführungsreihenfolge nichts, da jeder fehlgeschlagene Test ohnehin untersucht werden muss. Auch wenn nur zur Bestätigung, dass der Test auf dem Abfragesubmodul aufgrund des Fehlers, der auch auf dem datenerzeugenden Submodul festgestellt wurde, fehlschlägt.
Der beste Rat, den ich geben kann, besteht darin, die Tests so zu schreiben, dass leicht festgestellt werden kann, wann ein Fehler in einer Abhängigkeit dazu führt, dass der Test fehlschlägt.
quelle
Der Geruch, auf den Sie sich beziehen, ist die Anwendung der falschen Einschränkungen und Regeln auf Ihre Tests.
Unit Tests werden oft mit "automatisierten Tests" oder "automatisierten Tests durch Programmierer" verwechselt.
Unit Tests müssen klein, unabhängig und schnell sein.
Einige Leute lesen dies fälschlicherweise als "automatisierte Tests, die von einem Programmierer geschrieben wurden, müssen klein, unabhängig und schnell sein" . Wenn Ihre Tests jedoch nicht klein, unabhängig und schnell sind, handelt es sich nicht um Komponententests. Daher sollten, können oder müssen einige der Regeln für Komponententests nicht für Ihre Tests gelten. Ein einfaches Beispiel: Sie sollten Ihre Komponententests nach jedem Build ausführen, was bei automatisierten Tests, die nicht schnell sind, nicht erforderlich ist.
Während Ihre Tests keine Komponententests sind, bedeutet dies, dass Sie eine Regel überspringen können und eine gewisse Abhängigkeit zwischen den Tests haben dürfen. Sie haben jedoch auch herausgefunden, dass es andere Regeln gibt, die Sie möglicherweise übersehen haben und erneut einführen müssen - etwas für den Umfang einer anderen Frage .
quelle
Wie oben erwähnt, scheint das, was Sie ausführen, ein Integrationstest zu sein, Sie geben jedoch Folgendes an:
Und dies könnte ein guter Ort sein, um mit dem Refactoring zu beginnen. Das Modul, das Abfragen zu den Daten ausführt, sollte nicht von einer konkreten Implementierung des ersten (datengenerierenden) Moduls abhängig sein. Stattdessen ist es besser, eine Schnittstelle einzufügen, die die Methoden enthält, um an diese Daten zu gelangen, und diese kann dann zum Testen der Abfragen ausgeblendet werden.
z.B
Wenn Sie haben:
Stattdessen bevorzugen:
Dadurch wird die Abhängigkeit von Abfragen zu Ihrer Datenquelle aufgehoben, und Sie können leicht wiederholbare Komponententests für bestimmte Szenarien einrichten.
quelle
Die anderen Antworten erwähnen, dass die Testreihenfolge schlecht ist (was die meiste Zeit der Fall ist), aber es gibt einen guten Grund, die Reihenfolge bei der Testausführung durchzusetzen: Stellen Sie sicher, dass Ihre langsamen Tests (dh Integrationstests) nach Ihren schnelleren Tests (Tests) ausgeführt werden die nicht auf andere externe Ressourcen angewiesen sind). Dies stellt sicher, dass Sie mehr Tests schneller ausführen, was die Rückkopplungsschleife beschleunigen kann.
quelle