Wie verwende ich Unit-Tests als Informationsquelle?

8

Ein Kollege von mir war einmal auf einem Seminar über agile Entwicklung, wo er hörte, dass es möglich ist, Unit-Tests als technische Dokumentation zu verwenden. So etwas wie die Verwendung von Komponententests als Beispiel für die Verwendung der Klasse.

Eine schnelle Google-Suche lieferte TDD und Dokumentation , was beweist, dass dies möglich sein sollte. Wenn wir uns jedoch unseren Code ansehen, sehe ich, dass wir Unit-Tests offensichtlich nicht so implementiert haben.

Meiner Meinung nach dienen Unit-Tests dazu, Code als minimale Einheit zu testen, selbst mit Hilfe von Schein- und Fake-Klassen und -Funktionen.

Die Fragen sind also:

  • Ist es nicht die Aufgabe von Funktionstests zu zeigen, wie eine Klasse (oder eine Gruppe von Klassen) verwendet werden sollte?
  • Wenn es möglich ist, Komponententests als technische Dokumentation zu verwenden, gibt es einige Richtlinien für die Implementierung solcher Komponententests?
BЈовић
quelle
2
Unit-Tests sind eine Dokumentationsquelle, sollten jedoch häufig nicht die einzige Quelle sein.
Garrett Hall
"Aber wenn wir uns unseren Code ansehen, sehe ich, dass wir Unit-Tests offensichtlich nicht so implementiert haben." ...? Bedeutet das, dass Ihre Komponententests als Beispielcode nicht verständlich sind?
Steven Jeuris
@StevenJeuris Wir haben viele C ++ - Unit-Tests und einige sind lang (über 30 Zeilen). Ich habe nie in Unit-Tests nachgesehen, wie die Klasse verwendet wird. Dafür habe ich die Sauerstoffdokumentation verwendet, die wir haben, und den Code (wo eine bestimmte Klasse verwendet wird), und ich habe versucht, anhand des Klassencodes zu verstehen, was er tut. Das ist neu für mich
BЈовић

Antworten:

10

Wenn Sie TDD anwenden, entspricht jeder von Ihnen geschriebene Komponententest einer Funktionalität einer Klasse. Während Sie Tests schreiben, erstellen Sie tatsächlich die Klassenfunktionalitäten, Abhängigkeiten, Ausnahmen und auch die Klassendokumentation.

Wenn Sie TDD nicht anwenden, geben Ihnen Unit-Tests dennoch eine Vorstellung von der Klasse und ihren Funktionen. Unit-Test-Namen sind sehr aussagekräftig, sodass Sie meistens keine Dokumentation erstellen müssen.

Betrachten Sie einen Unit-Test wie

public void Customer_Service_Can_Register_New_Customers(){...}
public void Customer_Service_Cannot_Register_Customers_With_Duplicate_Emails(){...}

Dies sind selbstbeschreibende Methoden und auch leicht zu lesen. Sie dienen also auch als Dokumentation.

Mert Akcakaya
quelle
4

Unit-Tests dienen, wenn sie gut geschrieben sind, als Dokumentation einer Klasse oder Methode oder was auch immer.

Gut geschriebene führen zu mehr Verständnis, indem sie leicht herausfinden, was sie testen, aber selbst schlechte Tests geben dem Leser eine Vorstellung davon, wie sich das zu testende Objekt verhalten soll und welche Dinge der Autor für wichtig hielt, um es zu testen.

Es ist bekannt, dass ich Unit-Tests für externe Bibliotheken schreibe - nicht weil sie getestet werden müssen, sondern weil ich sicherstellen möchte, dass mein Verständnis der Bibliothek korrekt ist. Und wenn in Zukunft jemand Fragen dazu hat, wie ich Dinge benutze, gibt es mein Verständnis direkt im Testcode.

Michael Kohne
quelle
3
Netter Vorschlag zu Tests für externen Code!
1
Die Tests, die Ihr Verständnis einer Bibliothek überprüfen, werden als Charakterisierungstests bezeichnet .
Carl Manaster
2
@CarlManaster - Ich glaube , mich wie der Begriff Lerntest etwas besser - ich , dass Federn Klumpen kenne sie in mit Charakterisierung Tests, aber ich denke , dass es nützlich ist , Tests zu unterscheiden , sollten Sie etwas sicher (Tests Charakterisierung) von Tests ändern lassen , die nur sagen , Sie über etwas.
Michael Kohne
2

Während Funktionstests Ihnen helfen können, eine ganze Reihe von Funktionen zu verstehen, kann ein Komponententest Ihnen helfen, einen kleinen Codebereich zu verstehen (wie eine einzelne Methode).

Gute Komponententests dienen auch als gute technische Dokumentation, und es gibt einige Dinge, die beim Schreiben guter, einfacher und nützlicher Tests helfen können. Die zwei wichtigsten Punkte, auf die ich gestoßen bin, sind

  • Stellen Sie sicher, dass alle Ihre Tests unabhängig sind. Sie sollten in der Lage sein, eine beliebige Teilmenge von Tests in beliebiger Reihenfolge auszuführen.

  • Stellen Sie sicher, dass Sie in jedem Test nur eine einzige Sache testen. Dies hält Ihre Tests spezifisch, einfach, aber nicht spröde.

Oleksi
quelle
2

Die Idee von Tests als Akzeptanzkriterien / Dokumentation ist ausgezeichnet. Unit-Tests konzentrieren sich jedoch eher auf Architektur / Code-Design als auf User Stories. Der Versuch, Anwendungsfälle oder Anforderungen auf höherer Ebene zu dokumentieren, kann umständlich sein. Ich habe (noch) nicht viel darüber nachgedacht, aber Behavior Driven Development könnte bei diesem Problem helfen.

ptyx
quelle
1

Ich finde Beispiele viel einfacher zu lernen als Dokumentation und Unit-Tests. Nicht nur das, sondern sie zeigen mir am Beispiel, was ich NICHT mit einer Einheit machen soll.

Sie können jedoch nicht die einzige Form der Dokumentation sein. Man muss erkennen, dass alle Gehirne unterschiedlich funktionieren. Das ist eine Sache, von der ich denke, dass Leute, die empfehlen, NUR Unit-Tests als Dokumentation zu verwenden oder NUR den Code komplett vermissen. Noch ergreifender ist die Tatsache, dass selbst einzelne Gehirne verschiedene Dinge aus verschiedenen Medien lernen. Ich lerne etwas völlig anderes als ein Klassendiagramm, als nur Code zu betrachten oder API-Dokumente zu lesen.

Aber am Ende des Tages, wenn Diagramme und API-Dokumente alles sind, was Sie haben, dann bin ich wahrscheinlich durcheinander. Ich brauche Beispiele. Ich muss sehen, dass etwas benutzt wird. Ich könnte den Code danach durchsuchen und keine anderen Beispiele finden, an denen ich festhalte, aber das wird mir nie so viel sagen wie ein guter Komponententest.

Edward Strange
quelle
0

Das Testen ist heute ein Durcheinander von Begriffen, bei denen unterschiedliche Personen leicht unterschiedliche Bedeutungen haben und sich die Definitionen im Laufe der Zeit geändert haben.

Zum Beispiel war TDD früher etwas, das jetzt BDD genannt wird. Der Unterschied besteht darin, dass das, was Unit-Tests durch testgetriebene Entwicklung waren, jetzt ein viel feinerer Ansatz für Testmethoden ist (normalerweise generiert durch automatisierte Tools). Was früher TDD war, war eine etwas gröbere Art, Einheiten von der Größe von Klassen zu testen, was ich jetzt als Funktionstest bezeichne.

Die Idee, die Sie (in irgendeiner Form) testen können, ist, dass Sie einen Test schreiben können, der so aussieht, als würde der Benutzer eine Einheit Ihres Codes verwenden. Es wird ein Beispiel für die Dokumente und gleichzeitig ein Test.

Wenn Sie also eine einfache Netzwerkklasse hatten (zum Beispiel). Anstatt jede Methode einzeln zu testen, würden Sie sich dem Test nähern, dass die Klasse die Einheit ist, die getestet werden muss. Dann würde Ihr Komponententest die gesamte Einheit trainieren, indem Sie die Methode zum Initialisieren des Objekts aufrufen, den Host und den Port festlegen und eine Methode zum Senden von Daten aufrufen und möglicherweise auch eine Methode zum Empfangen aufrufen.

All dies kann in einen einzelnen "Komponententest" passen, der das Objekt testet, indem es in einen konfigurierten Zustand versetzt und zum Arbeiten gebracht wird. Weitere Unit-Tests würden es mit schlechten Daten durchführen, aber Sie müssen diese nicht in die Dokumentation aufnehmen.

Dies wird heute nicht als Komponententest betrachtet, aber alles hängt von Ihrer Definition einer Einheit ab.

gbjbaanb
quelle
Unit Testing und Functional Testing sind verschiedene Dinge. Wenn Sie anfangen, Verbindungen zu öffnen und zu schließen und echte Ressourcen zu verwenden, führen Sie Funktionstests durch, und diese Tests sind langsam, während die Komponententests sehr schnell sein müssen.
BЈовић
1
Sie haben sich in den Hype der Unit-Tests eingekauft. Sie dürfen nicht klein oder schnell sein oder etwas anderes als ein Mittel, um eine Codeeinheit isoliert zu testen. Der Rest ist nur so gemacht, dass das gebündelte Werkzeug korrekt erscheint. Sie können langsam sein und täglich laufen und groß und voller Beispiele sein, um eine Klasse gründlich zu bearbeiten. Es gibt keine einfach definierte Definition eines Komponententests. Lassen Sie sich nicht auf eine willkürliche Definition dessen ein, was Sie tun sollen, testen Sie Ihren Code isoliert, verspotten oder stubben Sie externe Verbindungen, und Sie haben gute Tests.
Gbjbaanb