Einzelnen Beitrag anzeigen

Benutzerbild von Phoenix
Phoenix
(Moderator)

Registriert seit: 25. Jun 2002
Ort: Hausach
7.640 Beiträge
 
#40

AW: Foren-Tage 2017 - Themen-"Wünsch-Dir-was"

  Alt 23. Jun 2017, 08:12
Eine praktische Einführung in Unit-Testing. Wie geht man da ran? Da ist bei mir der Zug irgendwann vorbeigefahren!
Und das gern im Zusammenhang mit Datenbankanwendungen.
Oder auch mit viel Oberfläche bzw. Benutzerinteraktion. Wie man das mit Unit-Tests testet war mir immer ein Rätsel.
Tja, Sherlock, das kann ich sogar als nicht-mehr-Delphianer beantworten

Kurzum: Oberflächen testet man Prinzipbedingt schon nicht mit Unit-Tests. Ein Unit-Test testet per Definition eine kleinstmögliche Einheit (Unit), das hat mit der Delphi-Unit nichts gemeinsam. Ein einzelner Unit-Test testet genau einen Effekt einer Methode. Hat die Methode mehrere Effekte, testet man jeden einzelnen mit einem einzelnen Unit-Test. Man kann auch den Konstruktor als Unit betrachten und dann den Initialzustand des Objektes überprüfen.

Sobald Du mehr als eine Klasse in einem Test abklopfst, bist Du schon aus der Welt der Unit-Tests raus und in der Welt der Integration-Tests angekommen.

Das funktioniert anfangs noch so ähnlich wie Unit-Tests - zumindest wenn alle am Test beteiligten Klassen noch in Deiner Kontrolle / in Deinem Projekt sind. Und solange man nicht weiter ausholt kann man die auch noch so schreiben wie die echten Unit-Tests.

Sobald eine Klasse in Deinem Integration-Test dabei aber die Grenzen Deines SUT (System under Test) verlassen (Datenbankzugriffsklassen, GUI-Klassen die native Apis callen wie die VCL, Netzwerkzugriffsklassen), dann ist es mit der einfachen Testbarkeit vorbei, weil Du dann immer darauf achten musst, dass das externe System (die Datenbank, das Ding im Netzwerk auf das zugegriffen wird, das UI-System) vor jedem einzelnen Test in einen wohldefinierten Zustand gebracht wird.

Am Ende des Tages verbringst Du bei dieser Art zu testen mehr Zeit damit, externe Systeme zu managen und Code zum Vorbereiten der Tests zu schreiben, als eigentlicher Code und als Testcode (der bei normalen Unit-Tests üblicherweise schon ein Vielfaches des zu testenden Codes beträgt). Insbesondere bei Datenbanken (herstellen der Test-DB etc.) und bei Services (noch schlimmer wenn die auch ne DB brauchen) ist man da gerne auf verlorenem Posten.

Tools wie z.B. TestComplete oder Ranorex können da leider auch nur bedingt helfen, und bringen alle ihre eigene Komplexität mit. Im Web siehts da ein klein bisschen besser aus, aber zum Trost auch nicht viel.

In der Praxis würde ich daher in den meisten Fällen vorschlagen, so viel wie möglich MVC zu fahren und dabei vor allem das M und den C sehr gut Unit- und Integration zu testen. Bei der View wird dann ausschließlich auf Model-Binding gesetzt (genau gar keine Logik dort) und darauf vertraut, dass der Lieferant seine UI-Elemente selber vernünftig getestet hat, und das eigentliche UI gar nicht automatisiert zu testen. Das einzige was man dann nämlich mit dem UI-Test testen würde wäre, ob ein Wert im Model auch richtig angezeigt wird und Events vom UI richtig am Controller ankommen. Das hat aber mit der Programmlogik an sich nichts zu tun. Und die Programmlogik, die Testbar im Controller bzw. dahinter (Services, Repositories etc.) sitzen sollte, hat dann mit dem UI nichts mehr zu tun und kann wirklich intensiv und gut getestet werden.
Sebastian Gingter
Phoenix - 不死鳥, Microsoft MVP, Rettungshundeführer
Über mich: Sebastian Gingter @ Thinktecture Mein Blog: https://gingter.org
  Mit Zitat antworten Zitat