Unterschied zwischen Unit Testing und testgetriebener Entwicklung

64

Wenn ich die Beschreibungen lese, verstehe ich, dass TDD-Tests vor dem Schreiben der Funktion und Unit-Tests danach durchgeführt werden.

Ist das der Hauptunterschied, oder können die beiden Begriffe nicht einmal als solche verglichen werden. Vielleicht ist Unit Testing ein integraler Bestandteil von TDD.

Shamim Hafiz
quelle

Antworten:

104

Unit Testing bezieht sich auf was Sie testen, TDD zu , wenn Sie testen.

Die beiden sind orthogonal.

Unit Testing bedeutet, einzelne Verhaltenseinheiten zu testen. Eine einzelne Verhaltenseinheit ist die kleinstmögliche Verhaltenseinheit, die einzeln für sich getestet werden kann. (Ich weiß, dass diese beiden Definitionen zirkulär sind, aber sie scheinen in der Praxis recht gut zu funktionieren.)

Sie können Komponententests schreiben, bevor Sie Ihren Code schreiben, nachdem Sie Ihren Code geschrieben haben oder während Sie Ihren Code schreiben.

TDD bedeutet (wie gesagt), dass Sie Ihre Tests Ihre Entwicklung (und Ihr Design) vorantreiben lassen. Das können Sie mit Unit-Tests, Funktionstests und Abnahmetests machen. Normalerweise verwenden Sie alle drei.

Der wichtigste Teil von TDD ist die mittleren D . Sie lassen sich von den Tests fahren . In den Tests erfahren Sie, was zu tun ist, was als Nächstes zu tun ist, wenn Sie fertig sind. Sie sagen Ihnen, was die API sein wird, was das Design ist. (Dies ist wichtig: Bei TDD geht es nicht darum, zuerst Tests zu schreiben. Es gibt viele Projekte, die zuerst Tests schreiben, aber nicht TDD üben. Das Schreiben von Tests als Erstes ist lediglich eine Voraussetzung dafür, dass die Tests die Entwicklung vorantreiben können.)

Jörg W. Mittag
quelle
1
Gute Antwort. würde hinzufügen ... TDD ist, wenn Sie Tests, um Sie und Funktionen, um Ihre Entwicklungsanstrengungen ziehen lassen ...
Martin
Sie sind jedoch nicht orthogonal. Sie können TDD nicht ohne Unit-Tests haben.
JacquesB
1
@JacquesB, warum? Unsere Tests sind per Definition nicht das, was Sie Unit-Tests nennen würden, sie hängen zu stark von der Infrastruktur und anderen Komponenten ab, aber wir haben immer noch genug Beobachtbarkeit, dass wir - zumindest einige von uns - TDD durchführen.
AProgrammer
3
@AndrewWillems: TDD bedeutet, dass die Tests die Entwicklung vorantreiben . Sie entscheiden nicht, wie das Design aussieht, die Tests sagen es Ihnen. Sie entscheiden nicht, woran Sie als nächstes arbeiten, sagen Ihnen die Tests. Sie entscheiden nicht, wann Sie fertig sind, sagen Ihnen die Tests. Es ist durchaus möglich, zuerst Tests zu schreiben und dann alles zu ignorieren, was sie Ihnen sagen. Beispielsweise könnten Sie zuerst Tests schreiben, aber dann weiterhin Code schreiben, auch wenn alle Tests grün sind. Mit anderen Worten: Sie schreiben Tests zuerst, aber Sie behandeln sie nur als Tests und lassen sie die Entwicklung nicht vorantreiben.
Jörg W Mittag
1
@ JörgWMittag Du magst es puristisch sehen, aber du weißt auch, dass TDD nicht schwarz-weiß ist. Eine vernünftige Verwendung von TDD würde es den Tests nicht erlauben, die Entwicklung vollständig voranzutreiben, und Tests entscheiden definitiv nicht immer, wie das Design aussieht (möglicherweise können Unit-Tests dies teilweise tun, aber keine Tests auf einer höheren Abstraktionsebene). Was ist mit Refactoring? Welches ist ein sehr wichtiger Aspekt von TDD. Auch in der realen Welt gibt es keine Möglichkeit, alles zu ignorieren, was der Test Ihnen sagt. Per Definition verwenden Sie, wenn Sie zuerst Tests schreiben, eine Art TDD.
NickL
21

Unit Testing ist eine Komponente von Test Driven Development

Sie können Komponententests durchführen, ohne eine testgetriebene Entwicklung durchzuführen. Sie können jedoch keine testgetriebene Entwicklung ohne Unit-Tests durchführen.

Wenn Sie herkömmliche Komponententests durchführen , schreiben Sie einen Test, nachdem Sie Ihren Code geschrieben haben.

Testgetriebener Entwicklungsansatz ist das Schreiben von Unit-Tests vor dem Schreiben von Code.

Die interessantesten Vorteile von TDD (IMHO) im Vergleich zu einfachen Unit-Tests:

  • Code ist im Voraus vollständig getesteter Code. Es ist schmerzlos zu testen.
  • Es zwingt Sie, Ihre Klassen richtig zu gestalten.
  • Es zwingt dich auch , es einfach dumm zu halten .
  • Der Kreislauf des Rot-Grün-Refaktors ist der absolute Aufschubkiller!

quelle
Haben Sie "unit" absichtlich in der Aussage verpasst: "Sie können jedoch keine testgetriebene Entwicklung ohne die Verwendung von testing durchführen." ?
Ratkok
@ratkok: nein das war nicht absichtlich. Lassen Sie mich das beheben.
Mir gefällt diese Definition am besten. Es ist besser in Worte zu fassen als andere Antworten.
15.
2
Möglicherweise können Sie TDD mithilfe von Modultests oder Systemtests anstelle von echten Komponententests durchführen. Ich würde es nicht empfehlen, da Sie einen großen Teil des Nutzens verlieren, wenn die Tests zu lange dauern, aber es ist nicht unmöglich.
Toby Speight
13

TDD und Unit Testing sind zwei sehr spezifische Begriffe, die häufig missbraucht werden.

TDD schreibt einen Test, der fehlschlägt, und schreibt dann die Mindestmenge an Code, die für die Ausführung erforderlich ist. Anschließend wird der Code überarbeitet, um ihn sauber zu machen. Dies geschieht in Zyklen, Fail -> Pass -> Refactor, wobei für jede bekannte Anforderung des Codes ein neuer Test hinzugefügt wird. In jüngerer Zeit hat sich TDD noch genauer mit dem Schreiben von Einheitentests in diesem Zyklus befasst, um es von ATDD (einer Teilmenge von BDD) zu unterscheiden, die Akzeptanztests in einem ähnlichen Zyklus schreibt.

Beim Unit Testing wird ein Code in kleinen, isolierten Einheiten getestet. Die allgemeine Verwirrung besteht darin, dass Sie, wenn Sie ein Unit-Test-Tool wie xUnit oder Rspec verwenden, Tests ausführen, für die Sie Unit-Tests schreiben. Dies ist nicht unbedingt wahr. Mit diesen Tools können beispielsweise Tests mit dem Selenium-Framework ausgeführt werden. In diesem Fall schreiben Sie Akzeptanztests mit einem Unit-Test-Runner. Unit-Tests sind sehr spezifische Tests, die sich auf ein kleines Stück Logik konzentrieren, das aus Gründen der Geschwindigkeit von allem anderen isoliert ist (sodass Sie sie häufig ausführen und schnelles Feedback zu neuen Fehlern erhalten können).

pdr
quelle
1
Die JUnit-Tests für JUnit selbst sind ein gutes Beispiel: Ein erheblicher Teil davon sind Funktionstests und Abnahmetests, keine Komponententests, obwohl sie in JUnit geschrieben sind. Der Schöpfer von JUnit ist zufällig auch der Schöpfer von TDD, und JUnit wurde unter Verwendung von TDD unter Verwendung einer erheblichen Anzahl von Funktionstests und Abnahmetests entwickelt. Abnahmetests sind ein wesentlicher Bestandteil von TDD.
Jörg W Mittag
6

TDD ist der Ansatz, die Testfälle vor der Entwicklung zu schreiben, wie Sie sagten, und dann schreibt der Entwickler den Code, um die Testfälle zu bestehen. Unit Testing ist ein Begriff, mit dem ein Test mit engem Geltungsbereich beschrieben wird, der sich von Systemtests, Integrationstests und Abnahmetests unterscheidet.

M.Sameer
quelle
3

TDD ist ein philosophischer Ansatz zum Schreiben von Code: Schreiben Sie zuerst die Tests. Die Tests, die Sie schreiben, sind Komponententests.

Tangurena
quelle
1

Die Art und Weise, wie ich die beiden voneinander trenne, besteht darin, zu berücksichtigen, dass es bei TDD weniger um das Testen als um das Entwerfen des Codes geht. Unit-Tests werden dann verwendet, um die Erwartungen für den Endcode festzulegen. Wenn der Endcode geschrieben ist und Tests (Spezifikationen) besteht, verfügen Sie über Code, der mithilfe von Tests erstellt wurde.

Grant Palin
quelle
1

Alles hervorragende Antworten. Ich möchte nur hinzufügen, dass Unit-Tests dazu tendieren, die "Unit" als kleine Komponente zu betrachten, während TDD auf Integrations- und Akzeptanztests hochskaliert.

(Einige TDD-Varianten betrachten die 'Einheit' als den kleinsten inkrementellen Schritt in Richtung der gewünschten Funktionalität ...)

Steven A. Lowe
quelle
sie sollten, aber nach meiner Erfahrung in der Realität tun sie es nicht. Unternehmen / Gruppen geben an, dass sie TDD durchführen, wenn sie Programmierer lediglich dazu zwingen, zuerst mit jUnit-Tests zu testen, und dann die Tatsache nutzen, dass alles bereits während der Entwicklung getestet wurde, um QA- und Integrationstests zu beseitigen (oder erheblich zu reduzieren).
Jwenting
1
@jwenting macht die Methodik nicht für die Mängel derer verantwortlich, die behaupten, sie zu praktizieren. Jedes Werkzeug kann missbraucht werden
Steven A. Lowe
1
Ich nicht, aber Sie müssen erkennen, dass es einen großen Unterschied zwischen dem, was TDD in der Theorie und dem, was es in der Realität ist, gibt. Und da die meisten Menschen (einschließlich OP) wahrscheinlich nur die Realität sehen, sollten sie auf den Unterschied hingewiesen werden.
20.
In Anbetracht dessen, dass es bei TDD um Design geht - warum sollte es Abnahmetests beinhalten? Wie würde es das Design "antreiben"?
Vitalii Isaenko
@VitaliiIsaenko Akzeptanztests bieten das höchste Maß an Scoping für Designs
Steven A. Lowe