Wie kritisieren Integrationstests das Design?

38

Ich lese in JB Rainsbergers Blogpost über integrierte Tests und frage mich, inwiefern ein Integrationstest bei unserem Design härter ist.

Wir schreiben mehr integrierte Tests, die größer sind und unser Design nicht so hart kritisieren wie Mikrotests

Alex.U
quelle
3
Die Frage ist verwirrend. "Inwiefern ist ein Integrationstest härter" ... "Integrierte Tests, die größer sind und unser Design nicht so hart kritisieren" - was nun?
AnoE
"integration test"! = "integrierter Test". Ich kenne. Ich mag es auch nicht, aber genau das bedeuten diese Worte. "Integrationstests" = "Tests, die die Integrationspunkte überprüfen (ohne Dinge zu integrieren)", während "integrierte Tests" = "(größere) Tests, die Dinge integrieren und das integrierte Ganze als eine einzige Sache überprüfen". Auf diese Weise werden diese Begriffe zu Gegensätzen.
JB Rainsberger

Antworten:

46

Mikrotests können zu gutem Design führen . Wenn Sie gute kleine Tests schreiben, testen Sie absichtlich eine kleine Menge Code und füllen die Lücken mit Scheinobjekten . Dies führt zu geringer Kopplung (Dinge sind nicht aufeinander angewiesen) und hohem Zusammenhalt (Dinge, die zusammen gehören, bleiben zusammen). Auf diese Weise können Sie beim Zurückkehren und Vornehmen von Änderungen leicht herausfinden, was für das, wonach Sie suchen, verantwortlich ist, und es ist weniger wahrscheinlich, dass Sie die Dinge bei der Durchführung der Änderung brechen. Dies wird nicht Ihr gesamtes Design lösen, aber es kann helfen.

In diesem Zusammenhang stellt JB Rainsberger fest, dass Sie wahrscheinlich ein Problem mit Ihrem Design haben, das die Schwierigkeit verursacht, und dass die Tests das Design implizit kritisieren, wenn Sie Schwierigkeiten beim Schreiben eines Komponententests haben. Er ist der Meinung, dass dies eine gute Sache ist, denn ohne die kleinen Tests, die dazu beitragen, Ihre Architektur in Einklang zu bringen, kann man leicht von guten Entwurfsmustern abweichen, die integrierte Tests nicht erfassen.

Update : Wie Rainsberger weiter unten bemerkt, wollte er nicht, dass Mikrotests gleichbedeutend mit Unit-Tests sind. Er hat auch eine detaillierte Antwort geliefert, die Ihnen einen tieferen Einblick in genau das geben kann, was er kommunizierte.

Thorin Jacobs
quelle
2
Ich stimme Ihrer Antwort im Prinzip zu, aber nicht so, wie Sie sie artikulieren. Jemand, der diese spezielle Frage stellt, wird wahrscheinlich nicht wissen, was die Begriffe "Verspotten", "Koppeln" und "Zusammenhalt" bedeuten, und Sie haben diese Begriffe in Ihrer Antwort nicht definiert.
Robert Harvey
3
Das ist besser, aber Sie geben Unit-Tests mehr Anerkennung, als ich denke, dass sie tatsächlich fällig sind. Unit-Tests informieren meist über die Testbarkeit Ihres Codes. Es ist weniger klar, ob das automatische Testen Ihres Codes bessere Kohäsions- und Kopplungseigenschaften verleiht, obwohl dies sicherlich einen positiven Einfluss hat. Ich denke auch, dass Sie einen "hohen Zusammenhalt" haben, der mit dem "Prinzip der alleinigen Verantwortung" verwechselt wird. Zusammenhalt bedeutet "Dinge, die zusammen gehören" (siehe Wikipedia-Artikel ).
Robert Harvey
10
Schließlich ist "Mikrotests" nicht der bevorzugte Begriff. Ich finde es toll, wenn Blogger sich ihre eigenen Fachbegriffe ausdenken.
Robert Harvey
2
@RubberDuck: Mikrotests (ca. 16.900 Ergebnisse) vs Unit Tests (ca. 193.000.000 Ergebnisse) . Nicht annähernd. Selbst wenn Sie Einheit und Tests zusammen zerdrücken, erhalten Sie immer noch 14 Millionen Ergebnisse.
Robert Harvey
5
Bitte setzen Sie nicht "Mikrotest" und "Komponententest" gleich (siehe meine Antwort für einige Details); Ansonsten habe ich das Gefühl, dass Sie verstanden haben, was ich zu beschreiben versuchte.
JB Rainsberger
28

Die extrem kurze Version: Kleinere Tests, da sie kleinere Teile des Systems ausführen, schränken natürlich das ein, was die Programmierer schreiben können, und dies schafft die Möglichkeit für schärferes Feedback (leichter zu bemerken / schwerer zu ignorieren). Lassen Sie mich hinzufügen, dass dies nicht unbedingt zu einem besseren Design führt, sondern vielmehr die Möglichkeit bietet, Designrisiken früher zu bemerken.

Zur Verdeutlichung: Wenn ich "Mikrotest" sage, meine ich "einen kleinen Test" und nichts weiter. Ich benutze diesen Begriff, weil ich nicht "Unit Test" meine: Ich möchte mich nicht in Debatten darüber verwickeln lassen, was eine "Unit" ausmacht. Es ist mir egal (zumindest nicht hier / jetzt). Zwei Leute werden sich wahrscheinlich leichter auf "klein" einigen als auf "Einheit", daher habe ich mich nach und nach entschieden, "Mikrotest" als neuen Standardbegriff für diese Idee zu verwenden.

Größere Tests, dh Tests, die größere Teile des Systems in ihrem "Action" -Teil ausführen, kritisieren das Design in der Regel nicht so klar und vollständig wie kleinere Tests. Stellen Sie sich die Menge aller Codebasen vor, die eine bestimmte Gruppe von Tests bestehen könnten, was bedeutet, dass ich den Code reorganisieren könnte und er diese Tests trotzdem bestehen würde. Für größere Tests ist dieses Set größer. Für kleinere Tests ist dieses Set kleiner. Anders gesagt, beschränken kleinere Tests das Design mehr, so dass weniger Designs sie bestehen können. Auf diese Weise können Mikrotests das Design stärker kritisieren.

Ich sage "härter", um das Bild eines Freundes zu zaubern, der dir direkt sagt, was du nicht hören willst, aber hören musst, und der dich anschreit, um Dringlichkeit auf eine Weise zu vermitteln, die andere Menschen möglicherweise nicht wohlfühlen tun. Integrierte Tests hingegen bleiben leise und deuten nur dann auf Probleme hin, wenn Sie keine Zeit und Energie mehr haben, diese zu beheben. Integrierte Tests machen es zu einfach, Designprobleme unter den Teppich zu kehren.

Bei umfangreicheren Tests (wie integrierten Tests) geraten Programmierer in der Regel durch Schlamperei in Schwierigkeiten: Sie haben genügend Freiheit, verworrenen Code zu schreiben, der die Tests irgendwie besteht, aber ihr Verständnis für diesen Code lässt schnell nach, sobald sie mit der nächsten Aufgabe fortfahren und andere haben unangemessene Schwierigkeiten, das verwirrte Design zu lesen. Hier liegt das Risiko, sich auf integrierte Tests zu verlassen. Bei kleineren Tests (wie Mikrotests) geraten Programmierer meistens in Schwierigkeiten, wenn sie zu viele Angaben machen: Sie beschränken die Tests, indem sie irrelevante Details hinzufügen, in der Regel durch Kopieren / Einfügen aus dem vorherigen Test, und malen sich dabei relativ schnell selbst in eine Ecke. Gute Nachrichten: Ich finde es viel einfacher und sicherer, überflüssige Details mehrere Stunden oder Tage nach dem Schreiben aus Tests zu entfernen, als Monate oder Jahre nach dem Schreiben verwickelten Produktionscode auseinander zu ziehen. Mit zunehmendem Fehler verursacht eine zu hohe Spezifikation immer schnelleren Schaden, und der Programmierer sieht früher, dass die Probleme behoben werden müssen. Ich halte das für eine Stärke: Ich stelle Probleme früher fest und behebe sie, bevor diese unsere Fähigkeit zum Hinzufügen von Funktionen einschränken.

JB Rainsberger
quelle
Was tun Sie gegen das Problem, dass Komponententests sich mehr auf ihre Mocks als auf den tatsächlichen Code stützen, was zu dem Problem führt, dass Tests scheinbar bestanden werden, aber tatsächlich nicht funktionieren, weil niemand die Mocks mit der Realität in Einklang gebracht hat?
Zan Lynx
@ZanLynx Ich habe ausführlich darüber geschrieben. Starten Sie hier: blog.thecodewhisperer.com/series#integrated-tests-are-a-scam
JB Rainsberger
9

Er meint, dass gutes Software-Design durch Unit-Tests besser informiert ist als durch Integrationstests.

Hier ist der Grund. Durch das Schreiben von Unit-Tests werden Sie gezwungen, Code zu schreiben, der Unit-Test-fähig ist. Unit-testbarer Code ist in der Regel ein besseres Design als Code ohne Unit-Tests.

Integrationstests informieren Ihren Code nicht auf die gleiche Weise, da Sie nur die äußere Schicht Ihrer Software testen, nicht die inneren Schnittstellen, die Ihre Software miteinander verbinden.

Robert Harvey
quelle