Ich habe gelesen diese Stelle darüber, wie man private Methoden testet. Ich teste sie normalerweise nicht, weil ich immer dachte, dass es schneller ist, nur öffentliche Methoden zu testen, die von außerhalb des Objekts aufgerufen werden. Testen Sie private Methoden? Sollte ich sie immer testen?
Antworten
Zu viele Anzeigen?Ich sehe, dass viele Leute in dieselbe Richtung denken: Testen Sie auf der öffentlichen Ebene, aber ist es nicht das, was unser QA-Team tut? Sie testen die Eingabe und die erwartete Ausgabe. Wenn wir als Entwickler nur die öffentlichen Methoden testen, dann wiederholen wir einfach die Arbeit der QA und schaffen keinen Mehrwert durch "Unit-Tests".
Es geht nicht nur um öffentliche oder private Methoden oder Funktionen, sondern auch um Implementierungsdetails. Private Funktionen sind nur ein Aspekt der Implementierungsdetails.
Das Unit-Testing ist schließlich ein White-Box-Testing-Ansatz. Wer zum Beispiel mit Hilfe der Coverage-Analyse Teile des Codes identifiziert, die beim Testen bisher vernachlässigt wurden, geht in die Implementierungsdetails.
A) Ja, Sie sollten die Details der Implementierung testen:
Stellen Sie sich eine Sortierfunktion vor, die aus Leistungsgründen eine private Implementierung von BubbleSort verwendet, wenn es bis zu 10 Elemente gibt, und eine private Implementierung eines anderen Sortierverfahrens (z. B. Heapsort), wenn es mehr als 10 Elemente gibt. Die öffentliche API ist die einer Sortierfunktion. Ihre Testsuite macht jedoch besser Gebrauch von dem Wissen, dass tatsächlich zwei Sortieralgorithmen verwendet werden.
In diesem Beispiel könnten Sie natürlich die Tests an der öffentlichen API durchführen. Dazu müsste man jedoch eine Reihe von Testfällen haben, die die Sortierfunktion mit mehr als 10 Elementen ausführen, so dass der Heapsort-Algorithmus ausreichend gut getestet ist. Allein das Vorhandensein solcher Testfälle ist ein Hinweis darauf, dass die Testsuite mit den Implementierungsdetails der Funktion verbunden ist.
Wenn sich die Implementierungsdetails der Sortierfunktion ändern, vielleicht in der Weise, dass die Grenze zwischen den beiden Sortieralgorithmen verschoben wird oder dass Heapsort durch Mergesort oder was auch immer ersetzt wird: Die bestehenden Tests werden weiterhin funktionieren. Ihr Wert ist dann allerdings fraglich, und sie müssen wahrscheinlich überarbeitet werden, um die geänderte Sortierfunktion besser zu testen. Mit anderen Worten, es wird ein Wartungsaufwand entstehen, obwohl die Tests auf der öffentlichen API waren.
B) Wie prüft man Details der Implementierung?
Ein Grund, warum viele Leute argumentieren, man solle keine privaten Funktionen oder Implementierungsdetails testen, ist, dass sich die Implementierungsdetails eher ändern können. Diese höhere Änderungswahrscheinlichkeit ist zumindest einer der Gründe dafür, Implementierungsdetails hinter Schnittstellen zu verstecken.
Nehmen wir nun an, dass die Implementierung hinter der Schnittstelle größere private Teile enthält, für die individuelle Tests an der internen Schnittstelle eine Option sein könnten. Einige Leute argumentieren, dass diese Teile nicht getestet werden sollten, wenn sie privat sind, sondern dass sie in etwas Öffentliches umgewandelt werden sollten. Sobald sie öffentlich sind, wäre ein Unit-Test für diesen Code in Ordnung.
Das ist interessant: Die Schnittstelle war zwar intern, konnte sich aber ändern, da es sich um ein Implementierungsdetail handelte. Wenn man dieselbe Schnittstelle öffentlich macht, wird sie auf magische Weise umgewandelt, nämlich in eine Schnittstelle, bei der es weniger wahrscheinlich ist, dass sie sich ändert. Offensichtlich hat diese Argumentation einen Schönheitsfehler.
Aber es steckt dennoch etwas Wahrheit dahinter: Beim Testen von Implementierungsdetails, insbesondere bei der Verwendung interner Schnittstellen, sollte man sich bemühen, Schnittstellen zu verwenden, die wahrscheinlich stabil bleiben werden. Ob eine Schnittstelle wahrscheinlich stabil ist, lässt sich jedoch nicht einfach danach entscheiden, ob sie öffentlich oder privat ist. In den Projekten aus der Welt, in der ich seit einiger Zeit arbeite, ändern sich öffentliche Schnittstellen auch oft genug, und viele private Schnittstellen sind seit Ewigkeiten unangetastet geblieben.
Dennoch ist es eine gute Faustregel, zuerst die "Vordertür" zu benutzen (siehe http://xunitpatterns.com/Principles%20of%20Test%20Automation.html ). Denken Sie aber daran, dass es "front door first" heißt und nicht "front door only".
C) Zusammenfassung
Testen Sie auch die Einzelheiten der Umsetzung. Testen Sie vorzugsweise an stabilen Schnittstellen (öffentlich oder privat). Wenn sich Implementierungsdetails ändern, müssen auch die Tests für die öffentliche API überarbeitet werden. Die Umwandlung einer privaten in eine öffentliche Schnittstelle ändert nicht auf magische Weise ihre Stabilität.