8 Stimmen

Verwendung von Zufälligkeiten und/oder Iterationen in Unit-Tests?

Bei Unit-Tests habe ich mir angewöhnt, Methoden zu testen, die einige reguläre Werte, einige Werte, die gegen den Methodenvertrag verstoßen, und alle Grenzfälle, die mir einfallen, anwenden.

Aber ist es eine schlechte Praxis, wenn

  • Wenn Sie einen Test mit zufälligen Werten durchführen, ist dies ein Wert innerhalb eines Bereichs, von dem Sie glauben, dass er keine Probleme verursachen sollte, so dass jedes Mal, wenn der Test läuft, ein anderer Wert eingegeben wird? Als eine Art ausführlicher Test für regelmäßige Werte?
  • Prüfung ganzer Bereiche durch Iteration ?

Ich habe das Gefühl, dass diese beiden Ansätze nicht gut sind. Bei Reichweitentests kann ich mir vorstellen, dass es einfach nicht praktikabel ist, das zu tun, weil es so viel Zeit in Anspruch nimmt, aber bei Zufälligkeit?

UPDATE :

Ich wende diese Technik selbst nicht an, ich habe mich nur darüber gewundert. Ich weiß jetzt, dass der Zufall ein gutes Werkzeug sein kann, wenn man ihn bei Bedarf reproduzierbar machen kann.
Die interessanteste Antwort war der "Fuzzing"-Tipp von Lieven:

http://en.wikipedia.org/wiki/Fuzz_testing

tx

5voto

fforw Punkte 5163

Unit-Tests müssen schnell sein. Wenn sie es nicht sind, werden die Leute sie nicht regelmäßig ausführen. Manchmal habe ich Code für die Überprüfung des gesamten Bereichs, aber @Ignore'd kommentierte es am Ende aus, weil es die Tests zu langsam machte. Wenn ich Zufallswerte verwenden würde, würde ich mich für einen PRNG mit festen Seeds entscheiden, so dass bei jedem Durchlauf tatsächlich dieselben Zahlen geprüft werden.

5voto

Gishu Punkte 130442
  1. Zufällige Eingabe - Die Tests würden nicht wiederholbar (erzeugen jedes Mal, wenn sie ausgeführt werden, einheitliche Ergebnisse und werden daher nicht als gute Einheitstests betrachtet. Tests sollten ihre Meinung nicht ändern.
  2. Range-Tests / RowTests - sind gut, solange sie nicht verlangsamen die Test-Suite laufen.. jeder Test sollte als laufen schnell wie möglich. (Eine Testreihe, die in 30 Sekunden erledigt ist, wird häufiger ausgeführt als eine, die 10 Minuten dauert) - vorzugsweise 100 ms oder weniger. Das heißt, jede Eingabe (Testdaten) sollte "repräsentativ" sein. Wenn alle Eingabewerte gleich sind, bringt das Testen jedes einzelnen keinen zusätzlichen Nutzen und ist nur routinemäßige Zahlenknackerei. Sie brauchen nur einen Repräsentanten aus dieser Gruppe von Werten. Sie brauchen auch Repräsentanten für Randbedingungen und "besondere" Werte.

Mehr über Leitlinien oder Daumenschrauben - siehe Was macht einen guten Einheitstest aus?

Abgesehen davon könnten die von Ihnen erwähnten Techniken gut geeignet sein, um finden. repräsentative Eingänge.. Benutzen Sie sie also, um SzenarioX zu finden, in dem Code fehlschlägt oder nicht richtig funktioniert - schreiben Sie dann einen wiederholbaren, schnellen, testbaren Unit-Test für dieses SzenarioX und fügen Sie ihn zu Ihrer Testsuite hinzu. Wenn Sie feststellen, dass diese Werkzeuge Ihnen weiterhin helfen, mehr gute Testfälle zu finden, bleiben Sie dabei.

Antwort auf die Klarstellung des Auftraggebers:

  • Wenn Sie bei jedem Testlauf den gleichen Startwert (Testeingabe) für Ihren Zufallsgenerator verwenden, ist Ihr Test nicht zufällig - die Werte können vorher festgelegt werden. Ein Unit-Test sollte jedoch idealerweise keine Eingabe/Ausgabe benötigen - deshalb haben xUnit-Testfälle die Signatur void TC().
  • Wenn Sie bei jedem Durchlauf unterschiedliche Seed-Werte verwenden, sind Ihre Tests zufällig und nicht wiederholbar. Natürlich können Sie den speziellen Seed-Wert in Ihren Log-Dateien ausfindig machen, um herauszufinden, was fehlgeschlagen ist (und den Fehler zu reproduzieren), aber ich mag es, wenn meine Tests mich sofort wissen lassen, was fehlgeschlagen ist - z. B. lässt mich ein roter TestConversionForEnums() wissen, dass der Code für die Enum-Konvertierung fehlerhaft ist, ohne dass ich ihn untersuchen muss.

Wiederholbar - bedeutet, dass der Test jedes Mal, wenn er auf dem SUT ausgeführt wird, dasselbe Ergebnis liefert (bestanden/nicht bestanden) und nicht "Kann ich den Testfehler erneut reproduzieren? Wiederholbar != Reproduzierbar ). Um es noch einmal zu wiederholen diese Art von exploratives Testen kann gut sein, um mehr Testfälle zu identifizieren, aber ich würde dies nicht zu meiner Testsuite hinzufügen, die ich jedes Mal ausführe, wenn ich im Laufe des Tages eine Codeänderung vornehme. Ich würde empfehlen, explorative Tests manuell durchzuführen, ein paar gute (manche sagen auch sadistische) Tester zu finden, die mit Hammer und Zange auf Ihren Code eindreschen - so finden Sie mehr Testfälle als mit einem Zufallsgenerator.

3voto

Nils Wloka Punkte 1503

Was Sie beschreiben, wird in der Regel als spezifikationsbasiertes Testen bezeichnet und wurde von Frameworks wie QuickCheck (Haskell), scalacheck (Scala) und Quviq QuickCheck (Erlang).

Datenbasierte Testwerkzeuge (wie z. B. DataProvider sur TestNG ) können ähnliche Ergebnisse erzielt werden.

Das zugrundeliegende Prinzip besteht darin, Eingabedaten für den zu prüfenden Gegenstand auf der Grundlage einer Art von Spezifikation zu generieren, und ist alles andere als eine "schlechte Praxis".

3voto

Lieven Keersmaekers Punkte 55277

Ich habe in meinen Testfällen Zufälligkeiten verwendet. Es hat mir einige Fehler in der SUT und einige Fehler in meinem Testfall beschert.

Beachten Sie, dass der Testfall durch die Verwendung von Zufallszahlen komplexer wird.

  • Sie benötigen eine Methode, um Ihren Testfall mit dem/den Zufallswert(en) auszuführen, bei dem er fehlgeschlagen ist
  • Sie müssen die für jeden Test verwendeten Zufallswerte protokollieren.
  • ...

Alles in allem schränke ich die Nutzung des Zufalls ein, lehne ihn aber nicht gänzlich ab. Wie jede Technik hat auch diese ihren Wert.

Für eine bessere Erklärung dessen, was Sie suchen, schlagen Sie den Begriff Fuzzing

2voto

Lasse V. Karlsen Punkte 364542

Was testen Sie? Den Zufallszahlengenerator? Oder Ihren Code?

Was ist, wenn Ihr Code einen Fehler enthält, der Zufallszahlen erzeugt?

Und wenn Sie ein Problem reproduzieren müssen, starten Sie dann den Test immer wieder neu und hoffen, dass er schließlich dieselbe Sequenz verwendet, die Sie hatten, als Sie das Problem entdeckten?

Wenn Sie sich entscheiden, einen Zufallszahlengenerator zu verwenden, um Daten zu erzeugen, sollten Sie ihm zumindest einen bekannten konstanten Wert geben, damit er leicht zu reproduzieren ist.

Mit anderen Worten: Ihre "Zufallszahlen" sind nur eine "Zahlenfolge, die mich nicht sonderlich interessiert".

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X