Laden...

Meinung gefragt - mein Aufbau von UnitTests

Erstellt von yngwie vor 14 Jahren Letzter Beitrag vor 14 Jahren 1.040 Views
Y
yngwie Themenstarter:in
238 Beiträge seit 2005
vor 14 Jahren
Meinung gefragt - mein Aufbau von UnitTests

Hallo Leute,

ich habe eine WindowsApplication die ich durchtesten will (ähnlich Integrationstest). Fast alle GUI-Click-Aktionen senden intern Commands (das Command-Pattern). Nun habe ich mir folgendes überlegt: Ich würde ein zweites Assembly namens "Test" (eine Klassenbibliothek) erstellen wo die Klassen mit UnitTests existieren sollen. Die Testmetoden darin könnten z.B. so aussehen:

1.) mache die alte Datenbank platt
2.) starte die WinApplication (Process.Start()?)
3.) hole aus WinApplication-Assembly eine Referenz auf das Objekt welches für Commands zuständig ist (Reflection?)
4.) manipuliere die DomainObjekte durch das versenden entsprechender Commands (new/delete/alter usw...)
5.) prüfe das Ergebnis mit Asserts
6.) beende die WinApplication

Dabei sind mir einige Punkte nicht ganz klar:
1.) werde ich bei dieser Vorgehensweise drei separate Processe am laufen haben - für NUnit, WinApplication und die Test.dll?
2.) mit welchen Problemen muss ich rechnen wenn die Test.dll und WinApplication.exe tatsächlich in zwei eigenständigen Processen laufen?
3.) Kann ich dann trotzdem aus Test.dll heraus auf die .NET-Objekte der WinApplication zugreifen?

Gerne würde ich ein paar Meinungen zu diesem "Konzept" hören. Kritik, Alternativvorschläge, technische Hinweise ... immer her damit 😃

5.742 Beiträge seit 2007
vor 14 Jahren

Hallo yngwie,

Gerne würde ich ein paar Meinungen zu diesem "Konzept" hören. Kritik, Alternativvorschläge, technische Hinweise ... immer her damit

Ganz ehrlich: Das ist Schrott.
Vergiss diese Idee lieber wieder ganz schnell.

UnitTests sollten möglichst unabhängig von der konkreten Anwendung durchgeführt werden (vor allem vom UI). Sie sollten weder abhängig von irgendwelchen Datenbanken, Dateisystemen, Processen usw. sein, noch von irgendwelchen anderen Umständen oder Komponenten.
Daher ist es wichtig, Klassen von Anfang an möglichst testbar zu machen: Abhängigkeiten durch Interfaces minimieren, um später Mocks und Stubs einsetzen zu können.
Außerdem sollten sie einfach und schnell sein; das Starten von Anwendungen und Verwendung von Reflection tragen hierzu nicht bei.

Was ich sagen will: Auch größter technischer Aufwand kann Versäumnisse beim Design hin zu testbaren Objekten nicht wettmachen.
Klingt jetzt vielleicht hart, fasst es aber gut zusammen. Und du hattest ja nach Kritik gefragt 😉

Auch will ich nicht sagen, ich könne es besser - im Gegenteil: Auch ich beschäftige mich derzeit intensiv damit, wie ich meine Klassen testen kann - und muss leider feststellen, wie kompliziert es ist, "gute" Tests zu schreiben.

Anders sieht es aus, wenn du das UI testen möchtest: Hier solltest du UI Automation verwenden; das "Einklinken" in andere Prozesse ist aber IMHO meist der falsche Weg.

Y
yngwie Themenstarter:in
238 Beiträge seit 2005
vor 14 Jahren

Hi winSharp93

UnitTests sollten möglichst unabhängig von der konkreten Anwendung durchgeführt werden (vor allem vom UI).

durch die Benutzung von Commands sollten die Tests relativ unabhängig vom UI sein.

Was die Unabhängigkeit von der konkreten Anwendung angeht ... 🙂 🙂 🙂 ...
Leider müssen die Tests im nachhinein geschrieben werden, da die Application schon längst fertig ist... d.h. es wird immer noch punktuell daran geschraubt, und dadurch dass die Architektur relativ unflexibel ist geht öfters mal nach einem BugFix irgend-etwas anderes kapputt. Oft muss dann an zig Stellen überprüfen werden ob alles noch OK ist, bzw. wo was nicht mehr stimmt. Deswegen sehe ich meine Tests einem Integrationstest am ähnlichsten und bin mir nicht ganz sicher ob die reine Lehre vom Aufbau der UnitTests hier 100%ig angewendet werden kann 😉

Was ich sagen will: Auch größter technischer Aufwand kann Versäumnisse beim Design hin zu testbaren Objekten nicht wettmachen.

Genau ! (und ich muss jetzt versuchen das Beste daraus zu machen)

um später Mocks und Stubs einsetzen zu können

Das stimmt natürlich. Bei mir ist die Versuchung recht groß die bestehende "Infrastruktur" zum Testen zu nutzen - sprich statt zu Mocken den existierenden Context zu verwenden.

Anders sieht es aus, wenn du das UI testen möchtest: Hier solltest du UI Automation verwenden

Nein nein, gerade die Oberfläche will ich ja gar nicht testen. Die meisten Aktionen werden zwar durch die Oberfläche getriggert, senden aber unter der Haube Commands zum CommandProcessor. Genau dies hoffe ich mir in meinen Tests zu nutze machen zu können um die Anzahl der LOCs im Testcode zu minimieren.

Es ist etwas kompliziert... so ein Kommando muss erst duch 3 Layer geschleift werden bis es in der eigentlichen BusinessLogic landet (deren Konsistenz interessiert mich am meisten) - und mit meinen Tests will ich sicherstellen das das Kommando unterwegs nicht kaputt gegangaen ist usw... Weiss echt nicht wie ich es sonst machen kann.

5.742 Beiträge seit 2007
vor 14 Jahren

durch die Benutzung von Commands sollten die Tests relativ unabhängig vom UI sein.

Warum testest du dann nicht die Commands direkt?
Muss dazu die ganze Anwendung gestartet sein und die Objekte aus einer anderen Anwendung stammen?
Den Grund für diesen Umweg sehe ich nicht 🤔

Es ist etwas kompliziert... so ein Kommando muss erst duch 3 Layer geschleift werden bis es in der eigentlichen BusinessLogic landet (deren Konsistenz interessiert mich am meisten)

Dann würde ich dir empfehlen, erst einmal die Businesslogik zu testen.
Das scheint ja auf jeden Fall unabhängig vom UI möglich zu sein, oder?

Y
yngwie Themenstarter:in
238 Beiträge seit 2005
vor 14 Jahren

Hallo winSharp93,

Muss dazu die ganze Anwendung gestartet sein und die Objekte aus einer anderen Anwendung stammen

ich muss testen können ob vorgenommene Änderungen auch nach dem Restart der Application noch da sind (sauber in der DB abgelegt sind + wieder in die BusinessObjekte geladen). Dafür müsste ich die "Application under test" von aussen starten, beenden und restarten können... das ist einer der Gründe warum ich der Meinung bin dass eine zweite "Application" notwendig ist. Kennst du einen anderen Weg so etwas umzusetzten?

Warum testest du dann nicht die Commands direkt? Kannst du vielleicht diesen Gedanken etwas ausführlicher beschreiben, ich versteh es gerade nicht 😦 Danke

5.742 Beiträge seit 2007
vor 14 Jahren

ich muss testen können ob vorgenommene Änderungen auch nach dem Restart der Application noch da sind (sauber in der DB abgelegt sind + wieder in die BusinessObjekte geladen).

Wie gesagt: Auch da nicht "alles auf einmal", sondern schrittweise testen.

Warum testest du dann nicht die Commands direkt?
Kannst du vielleicht diesen Gedanken etwas ausführlicher beschreiben, ich versteh es gerade nicht

Nehmen wir an, du hast ein Command DeleteAllUsers.
Dieses wird normalerweise von einem Button des UIs ausgelöst.

Nun gehst du allerdings hin und instanzierst dieses Command in einem Test und lässt es auf eine Datenbank, die du vorher mit wohl definierten Daten gefüllt hast, los (Zwar wäre es hier besser, mit Stubs und Mocks zu arbeiten, sodass man nicht von der Datenbank abhängig ist - aber das scheint in deinem Projekt aufgrund der "Altlasten" nicht möglich zu sein).
Danach prüfst du, ob tatsächlich alle Benutzer aus der Datenbank entfernt worden sind.

Beim UnitTesting geht es eigentlich weniger darum, dass die Anwendung als solche funktioniert, sondern mehr, dass die einzelnen Komponenten ihre Arbeit wie erwartet durchführen.

5.941 Beiträge seit 2005
vor 14 Jahren

--
Microsoft MVP - Visual Developer ASP / ASP.NET, Switzerland 2007 - 2011

Y
yngwie Themenstarter:in
238 Beiträge seit 2005
vor 14 Jahren

Hi Peter,

danke für den Link! Der Anfang sieht vielversprechend aus... warte auf den zweiten Teil

Gruß