Ist es besser, eines von beiden zu haben?
- Deterministische Testsuite, die zum Erfolg derselben Tests führt
- Nicht deterministische Testsuite, die möglicherweise mehr Fälle abdeckt
?
Beispiel: Sie schreiben eine Testsuite, um die Controller-Funktionalität in einer MVC-Anwendung zu testen. Der Controller benötigt während des Tests Anwendungsdaten aus einer Datenbank als Eingabe. Hierfür gibt es zwei Möglichkeiten:
- Sie codieren fest, welche Zeile (n) aus der Testdatenbank als Eingabe ausgewählt sind (z. B. die 10. und die 412. Zeile).
- Sie verwenden einen Zufallszahlengenerator, um die Daten pseudozufällig aus der Datenbank auszuwählen (zwei Zeilen, die von einem Zufallszahlengenerator ausgewählt wurden).
Der erste ist deterministisch: Jeder Testlauf für dieselbe Coderevision sollte dasselbe Ergebnis liefern. Der zweite ist nicht deterministisch: Jeder Durchlauf der Testsuite hat die Möglichkeit, ein anderes Ergebnis zu erzielen. Die zufällig ausgewählten Daten könnten jedoch eine bessere Darstellung von Datenkantenfällen sein. Es könnte einen Benutzer simulieren, der unsere Steuerungen besser mit unvorhersehbaren Daten füttert.
Was sind Gründe, sich für einen anderen zu entscheiden?
Antworten:
Wenn Sie bei jedem Durchlauf der Testsuite die Möglichkeit haben, ein anderes Ergebnis zu erzielen, ist der Test nahezu wertlos. Wenn die Suite einen Fehler anzeigt, besteht eine hohe Wahrscheinlichkeit, dass Sie ihn nicht reproduzieren können, und wenn Sie versuchen, den Fehler zu beheben Fehler, Sie können nicht überprüfen, ob Ihr Fix funktioniert.
Wenn Sie also glauben, dass Sie eine Art Zufallszahlengenerator zum Generieren Ihrer Testdaten verwenden müssen, müssen Sie entweder sicherstellen, dass Sie den Generator immer mit demselben Startwert initialisieren, oder Ihre zufälligen Testdaten in einer Datei beibehalten, bevor Sie sie in Ihren Test einfügen. So können Sie den Test mit genau denselben Daten wie zuvor erneut ausführen. Auf diese Weise können Sie jeden nicht deterministischen Test in einen deterministischen Test umwandeln.
BEARBEITEN: Die Verwendung eines Zufallszahlengenerators zum Auswählen einiger Testdaten ist meiner Meinung nach manchmal ein Zeichen dafür, dass man beim Auswählen guter Testdaten zu faul ist . Anstatt 100.000 zufällig ausgewählte Testwerte zu werfen und zu hoffen, dass dies ausreicht, um alle schwerwiegenden Fehler zufällig zu entdecken, sollten Sie Ihr Gehirn besser nutzen, 10 bis 20 "interessante" Fälle auswählen und sie für die Testsuite verwenden. Dies führt nicht nur zu einer besseren Qualität Ihrer Tests, sondern auch zu einer viel höheren Leistung der Suite.
quelle
Sowohl deterministisch als auch nicht deterministisch haben einen Platz
Ich würde sie wie folgt aufteilen:
Unit-Tests.
Diese sollten deterministische, wiederholbare Tests mit genau den gleichen Daten jedes Mal haben. Unit-Tests begleiten bestimmte, isolierte Codeabschnitte und sollten sie deterministisch testen.
Funktions- und Eingangsstresstests.
Diese können den nicht deterministischen Ansatz mit den folgenden Einschränkungen verwenden:
quelle
Beide.
Deterministische und nicht deterministische Tests haben unterschiedliche Anwendungsfälle und unterschiedliche Werte für Ihre Suite. Im Allgemeinen kann nicht deterministisch nicht die gleiche Präzision wie deterministisches Testen liefern, das langsam zu "nicht deterministischem Testen liefert keinen Wert" herangewachsen ist. Das ist falsch. Sie können weniger genau sein, aber sie können auch viel breiter sein, was seine eigenen Vorteile hat.
Nehmen wir ein Beispiel: Sie schreiben eine Funktion, die eine Liste von ganzen Zahlen sortiert. Was wären einige der deterministischen Komponententests, die Sie nützlich finden würden?
NaN
,INT_MIN
undINT_MAX
Und das ist nur eine Sortierfunktion! Sicher, Sie könnten argumentieren, dass einige davon unnötig sind oder dass einige davon mit informeller Begründung ausgeschlossen werden können. Aber wir sind Ingenieure und wir haben informelle Argumente in die Luft jagen sehen. Wir wissen, dass wir nicht schlau genug sind, um die Systeme, die wir gebaut haben, vollständig zu verstehen oder die Komplexität in unseren Köpfen zu behalten. Deshalb schreiben wir in erster Linie Tests. Das Hinzufügen nicht deterministischer Tests besagt lediglich, dass wir möglicherweise nicht klug genug sind, um alle guten Tests a priori zu kennen. Indem Sie semi-zufällige Daten in Ihre Funktion einfließen lassen, ist die Wahrscheinlichkeit sehr viel höher, dass Sie einen Randfall finden, den Sie verpasst haben.
Das schließt natürlich auch deterministische Tests nicht aus. Nicht deterministische Tests helfen dabei, Fehler in großen Programmbereichen zu finden. Sobald Sie die Fehler gefunden haben, müssen Sie nachvollziehbar nachweisen, dass Sie sie behoben haben. So:
Beachten Sie, dass dies bedeutet, dass viele fundierte Ratschläge zu Komponententests nicht unbedingt für nicht deterministische Tests gelten. Zum Beispiel, dass sie schnell sein müssen. Low-Level-Eigenschaftstests sollten schnell sein, aber ein nicht deterministischer Test wie "simulieren Sie, dass ein Benutzer zufällig auf Schaltflächen auf Ihrer Website klickt, und stellen Sie sicher, dass Sie niemals einen 500-Fehler erhalten" sollte die Vollständigkeit der Geschwindigkeit vorziehen. Lassen Sie einfach einen solchen Test unabhängig von Ihrem Erstellungsprozess ausführen, damit die Entwicklung nicht verlangsamt wird. Führen Sie es beispielsweise auf einer eigenen privaten Staging-Box aus.
quelle
Sie wollen nicht deterministisch oder nicht deterministisch.
Was Sie vielleicht wollen, ist "immer gleich" vs. "nicht immer gleich".
Zum Beispiel könnten Sie eine Build-Nummer haben, die mit jedem Build zunimmt, und wenn Sie einige Zufallszahlen wollen, initialisieren Sie einen Zufallszahlengenerator mit der Build-Nummer als Startwert. Sie führen also bei jedem Build Ihre Tests mit unterschiedlichen Werten durch, sodass Sie mehr Chancen haben, Fehler zu finden.
Sobald jedoch ein Fehler gefunden wurde, müssen Sie den Test nur mit derselben Build-Nummer ausführen, und er ist reproduzierbar.
quelle