Werden Unit-Tests wirklich als Dokumentation verwendet?

22

Ich kann nicht zählen, wie oft ich Aussagen im Sinne von "Komponententests sind eine sehr wichtige Quelle für die Dokumentation des getesteten Codes" gelesen habe. Ich leugne nicht, dass sie wahr sind.

Persönlich habe ich sie jedoch noch nie als Dokumentation verwendet. Für die typischen Frameworks, die ich verwende, dokumentieren die Methodendeklarationen ihr Verhalten und das ist alles, was ich brauche. Und ich gehe davon aus, dass die Komponententests alle in dieser Dokumentation angegebenen Daten sichern, plus wahrscheinlich einige weitere interne Daten, sodass auf der einen Seite die Dokumentation dupliziert wird, während auf der anderen Seite möglicherweise weitere Daten hinzugefügt werden, die irrelevant sind.

Die Frage ist also: Wann werden Unit-Tests als Dokumentation verwendet? Wann decken die Kommentare nicht alles ab? Durch Entwickler, die die Quelle erweitern? Und was enthüllen sie, was nützlich und relevant sein kann, was die Dokumentation selbst nicht enthüllen kann?

stijn
quelle
4
Nie gedacht, Unit-Test direkt als Dokumentation zu verwenden. Ich denke, die Unit-Tests sind oft unleserlich, weil viele Entwickler sich nicht die Zeit nehmen, sie klar zu schreiben.
SuperM
10
Kommentare sind möglicherweise falsch.
2
Ich weiß, dass Sie speziell nach Komponententests fragen, aber ich würde auch feststellen, dass Integrationstests / Systemtests auch eine wirklich nützliche Dokumentation sind, nur auf einer anderen Ebene
jk.
3
Ich habe Unit-Tests gesehen, die besser als "Unit-Experimente" charakterisiert werden könnten. Ihre Abhängigkeit von äußeren Faktoren machte sie nahezu unbrauchbar. Sie waren auch sehr unklar. (Ja, ich habe das langfristige Ziel, sie zu verbessern, aber ich mache auch andere Dinge ...)
Donal Fellows
4
@Ant-Unit-Tests rufen den realen Code auf, dokumentieren die erwartete Antwort und vergleichen sie mit der tatsächlichen Antwort. Ob der aufgerufene Code korrekt ist oder nicht, ist nicht der Punkt - die Tests dokumentieren, wie man ihn aufruft.

Antworten:

17

Sie sind KEINE ABSOLUTE Referenzdokumentation

Beachten Sie, dass viele der folgenden Punkte auch auf Kommentare zutreffen, da sie möglicherweise nicht mehr mit dem Code synchronisiert sind, wie z. B. Tests (obwohl dies weniger durchsetzbar ist).

Also am Ende, der beste Weg , den Code zu verstehen ist lesbar funktionierenden Code zu haben .

Wenn es überhaupt möglich ist und keine fest verdrahteten Codeabschnitte auf niedriger Ebene oder besonders schwierige Bedingungen geschrieben werden, ist eine zusätzliche Dokumentation von entscheidender Bedeutung.

  • Tests können unvollständig sein:
    • Die API wurde geändert und nicht getestet.
    • Die Person, die den Code geschrieben hat, hat die Tests für die am einfachsten zu testenden Methoden anstatt für die wichtigsten zu testenden Methoden geschrieben und hatte dann keine Zeit zum Beenden.
  • Tests können veraltet sein.
  • Tests können auf nicht offensichtliche Weise kurzgeschlossen und nicht tatsächlich ausgeführt werden.

ABER sie sind NOCH eine HILFREICHE Ergänzung zur Dokumentation

Wenn ich jedoch im Zweifel bin, was eine bestimmte Klasse macht, insbesondere wenn sie ziemlich langwierig ist, undurchsichtig ist und keine Kommentare enthält (Sie kennen die Art ...), versuche ich schnell, die Testklasse (n) zu finden und Folgendes zu überprüfen:

  • was sie tatsächlich zu überprüfen versuchen (gibt einen Hinweis auf die wichtigsten Leckerbissen, es sei denn, der Entwickler hat den oben genannten Fehler begangen, nur die "einfachen" Tests zu implementieren),
  • und wenn es Eckfälle gibt.

Wenn sie mit einem BDD-Stil geschrieben wurden , geben sie außerdem eine recht gute Definition des Klassenvertrags . Öffnen Sie Ihre IDE (oder verwenden Sie grep), um nur Methodennamen und tada anzuzeigen: Sie haben eine Liste von Verhaltensweisen.

Regressionen und Bugs benötigen ebenfalls Tests

Es ist auch eine gute Praxis, Tests für die Regression und für Fehlerberichte zu schreiben: Sie beheben etwas, Sie schreiben einen Test, um den Fall zu reproduzieren. Wenn Sie auf diese zurückblicken, ist dies beispielsweise eine gute Möglichkeit, den entsprechenden Fehlerbericht und alle Details zu einem alten Problem zu finden.

Ich würde sagen, sie sind eine gute Ergänzung zur echten Dokumentation und zumindest eine wertvolle Ressource in dieser Hinsicht. Es ist ein gutes Werkzeug, wenn es richtig verwendet wird. Wenn Sie früh mit dem Testen Ihres Projekts beginnen und es zur Gewohnheit machen, KÖNNTE es eine sehr gute Referenzdokumentation sein. Gehen Sie bei einem vorhandenen Projekt mit schlechten Codierungsgewohnheiten, die die Codebasis bereits stinken, vorsichtig damit um.

Haylem
quelle
Darf ich fragen, warum ich abgelehnt wurde? Was reizt Sie da drin oder was stimmen Sie nicht zu?
Haylem
2
Der (IMO) beste Teil Ihres Arguments ist in der kleinsten Schrift geschrieben - der beste Weg, Code zu verstehen, besteht darin, überhaupt lesbaren Code zu haben. Ich würde das in "lesbaren und funktionierenden Code" ändern, aber ich stimme zu. Wenn Sie sich dann noch einmal Unit-Tests ansehen - laufende Tests funktionieren mit Code (und sollten wie jeder Code lesbar sein), so dass es eigentlich eine ziemlich gute (wenn auch oft zu lokale) Dokumentation ist, wenn sie gut durchgeführt werden.
Joris Timmermans
@ MadKeithV: danke. Ich habe ein Update für "lesbaren und funktionierenden Code" durchgeführt und dieses Bit nach oben verschoben.
Haylem
11

Eine Interpretation ist, dass Unit-Tests "ausführbare Dokumentation" sind. Sie können die Komponententests für den Code ausführen und sehen, ob die Leistung noch so ist, als die Tests bestanden wurden, oder nicht. Auf diese Weise "dokumentiert" das Gerät die Funktionalität des Systems zu einem bestimmten Zeitpunkt auf ausführbare Weise.

Andererseits habe ich auch nur selten tatsächlich Unit-Test-Code als "Dokumentation" gelesen, um die Funktionalität zu verstehen. Ein einzelner Komponententest ist zu lokalisiert, spezifisch und abstrakt, um Ihnen viel über das tatsächliche System zu erzählen, das hinter der getesteten Klasse steht.

Joris Timmermans
quelle
5

Wenn durch Dokumentation meinen Sie ich etwas will, um herauszufinden , wie der Code funktioniert dann Unit - Tests sind perfekte kleine Beispiele dafür , wie Einheiten der Code funktioniert mit jedem erwartet , Grenzfälle und Fehler (auch bekannt als Bugs ) Fälle. Außerdem können Ihre Tests erstellt werden, bevor der Code geschrieben wird. Dies ist die Grundlage dafür, was der Code aus geschäftlicher Sicht bzw. aus Sicht der Anforderungen tun sollte.

Ersetzen sie die Dokumentation? Nein.

Sind sie eine nützliche Ergänzung zur Dokumentation? Ja.

Sardathrion - Setzen Sie Monica wieder ein
quelle
4

Ich sehe Unit-Tests als:

  • Ein Weg, um zu beweisen, dass die Dokumentation korrekt ist (vorausgesetzt, die Dokumentation entspricht der API-Implementierung).
  • eine Möglichkeit, einem Entwickler zu demonstrieren, wie eine bestimmte Funktion verwendet wird; Unit-Test-Geräte / Unit-Test selbst sind in der Regel so klein, dass man schnell daraus lernen kann.
  • und offensichtlich, um einen Regressionsfehler zu entdecken.

In gewissem Umfang können sie als Ergänzung zu einer vorhandenen Dokumentation angesehen werden, jedoch nicht als Dokumentation.

David Andreoletti
quelle
3

Ich beantworte Ihre Frage, indem ich Ihnen eine andere stelle.

Wie oft haben Sie bei der Arbeit mit einer neuen API / Routine Hilfe aufgerufen, um nach einem Codebeispiel für das zu verwendende Element zu suchen? Gelingt es Ihnen nicht, für eine Online-Suche von Codebeispielen auf Google umzuschalten?

Genau dann würden Sie Unit-Tests als Dokumentation verwenden.

  • In der Tat können die Unit - Tests ein wenig strenger sein als normale Code - Beispiele, da Sie sollten mehrere Tests (Beispiele) haben.
  • Hoffentlich veranschaulichen Ihre Unit-Tests die ordnungsgemäße Verwendung. ZB zeigen sie alle wesentlichen Abhängigkeiten entweder über normale Objekte oder über Scheinobjekte deutlich an. (Ansonsten sind sie keine besonders guten Komponententests.)
  • HINWEIS: Wenn Ihre Kommentare oder "normale Dokumentation" Codebeispiele enthalten, verstoßen Sie tatsächlich gegen die DRY-Prinzipien. Und diese Codebeispiele können mit der Zeit leicht falsch werden, während dies bei regelmäßig ausgeführten Komponententests deutlich weniger wahrscheinlich ist.
  • Wenn die Unit-Tests gründlich sind (normalerweise ein großes Wenn ), sollten sie zusätzliche Informationen liefern:
    • Alle bekannten Randfälle übersichtlich dargestellt.
    • Alle erwarteten Ausnahmen, die ausgelöst werden können.
    • Alle zuvor gefundenen Fehler (dies ist wahrscheinlich nützlicher, wenn Sie das zu testende Gerät erweitern, als wenn Sie einen neuen Client für das Gerät schreiben).
    • Alle zugrunde liegenden Geschäftsregeln, die der Einheit zugeordnet sind. (wenn überhaupt)

Ich vermute, es gibt einige Gründe, warum Unit-Tests nicht als Dokumentation verwendet werden, obwohl sie eine hervorragende Ergänzung zu herkömmlicherer Dokumentation darstellen könnten :

  • Ich würde es wagen vorzuschlagen, dass die Tests selbst oft nicht gut genug für diesen Zweck geschrieben sind. Andere Antworten haben bereits auf folgende Tests angespielt:
    • Unvollständig.
    • Verwirrend. (Ich habe Testfälle gesehen, bei denen die getestete Methode nicht direkt aufgerufen wird. Bevor sie aufgerufen wird, befinden Sie sich in einer dreiviertel Ebene des Aufrufstapels. Die Voraussetzungen für den Aufruf der Methode sind an verschiedenen Stellen in einer komplexen Klassenhierarchie verteilt. )
    • Veraltet. (In der Regel sollten Tests fehlschlagen, wenn sie veraltet sind. Dies ist jedoch nicht immer der Fall.)
  • In der Regel sind bereits zahlreiche Beispiele für die Verwendung im Produktionscode verfügbar, wenn ein Beispiel benötigt wird.
  • Das zu testende Gerät ist so gut geschrieben (selbstdokumentierend), dass die Methoden keine Beispiele benötigen. Ich wünsche!
  • Nach meiner Erfahrung als Programmierer sind wir sehr daran interessiert, am nächsten Dienstag ins Deep End und ins RTFM einzuspringen ...
  • Dokumentation und Kommentare, die gegen das DRY-Prinzip verstoßen.
Desillusioniert
quelle
2

TL; DR Unit-Tests und API-Kommentare ergänzen sich - einige Dinge lassen sich am besten im Code und andere in der Prosa beschreiben.

Unit-Tests sind hauptsächlich nützlich, um Sonderfälle und Randbedingungen zu dokumentieren, die in API-Kommentaren nur schwer (und umständlich) zu beschreiben sind. Außerdem richten sich die API-Kommentare in der Regel an Personen, die die API verwenden möchten.

Wenn Sie den Code ändern möchten, müssen Sie in der Regel viel mehr wissen, und einige davon lassen sich nur schwer in Kommentare einfügen (und diese Kommentare veralten schnell). In diesem Fall dient ein Komponententest auch als Dokumentation.

Ein Beispiel: Sie haben eine Methode m (a, b), die eine bestimmte Berechnung durchführt. Aufgrund von Abwärtskompatibilitätsanforderungen müssen Eingaben in Sonderfällen von a=0und vorgenommen werden a=-1, jedoch nur, wenn bNULL ist. Das in einen Kommentar einzufügen ist kompliziert, ausführlich und wird wahrscheinlich veralten, wenn die Anforderung später entfernt wird.

Wenn Sie einige Komponententests durchführen, bei denen das Verhalten überprüft wird m(0, NULL), erhalten m(-1, x)Sie mehrere Vorteile:

  • Die Beschreibung des richtigen Verhaltens ist klar, Missverständnisse werden reduziert
  • Die Benutzer können die Anforderung nicht übersehen, wenn sie den Code ändern, im Gegensatz zu einem Kommentar
sleske
quelle
Wenn dieses Verhalten in Ihrem Beispiel jedoch überhaupt nicht im Kommentar dokumentiert ist, kann ein Benutzer unerwartete Ergebnisse für diesen Randfall erhalten. Welches ist nicht gerade eine gute Sache.
28.
@stijn: Stimmt. In diesem Fall ist es wahrscheinlich am besten, den Sonderfall in den Dokumenten kurz zu erwähnen und die Unit-Tests auf die unordentlichen Details zu überprüfen.
sleske