Ich bin überzeugt von dieser Präsentation und anderen Kommentaren hier auf der Seite, die ich zum Komponententest lernen muss. Ich weiß auch, dass es viele Fragen darüber gab, was Unit Testing hier ist. Jedes Mal, wenn ich darüber nachdenke, wie es in der Anwendung, an der ich gerade arbeite, gemacht werden soll, gehe ich verwirrt davon. Es ist eine Xulrunner-Anwendung, und ein Großteil der Logik ist ereignisbasiert - wenn ein Benutzer hier klickt, findet diese Aktion statt.
Oft sind die Beispiele, die ich zum Testen sehe, Testklassen - sie instantiieren ein Objekt, geben ihm Scheindaten und überprüfen danach die Eigenschaften des Objekts. Das macht für mich Sinn - aber was ist mit den nicht objekt-orientierten Stücken?
Dieser Typ erwähnte diese GUI -basierte Unit-Tests sind in den meisten Test-Frameworks schwierig, vielleicht ist das das Problem. Die oben verlinkte Präsentation erwähnt, dass jeder Test nur eine Klasse, eine Methode nach der anderen berühren sollte. Das scheint auszuschließen, was ich versuche zu tun.
Also die Frage - wie testet eine Einheit prozeduralen oder ereignisbasierten Code? Geben Sie einen Link zu einer guten Dokumentation an oder erklären Sie es selbst.
Nebenbei bemerkt, ich habe auch die Herausforderung, kein Testframework gefunden zu haben, das zum Testen von Xulrunner-Apps eingerichtet ist - es scheint, dass die Tools noch nicht entwickelt sind. Ich stelle mir vor, dass dies peripherer ist, als wenn ich die Konzepte verstehe, testbaren Code schreibe und Komponententests anwende.
Die Idee des Komponententests besteht darin, mit jedem Test kleine Codeabschnitte zu testen. In einem ereignisbasierten System könnte eine Art von Unit-Tests, die Sie ausführen könnten, darin bestehen, zu testen, wie Ihre Event-Handler auf verschiedene Ereignisse reagieren. So kann Ihr Komponententest einen Aspekt Ihres Programms in einen bestimmten Zustand setzen, dann die Ereignis-Listener-Methode direkt aufrufen und schließlich den nachfolgenden Status Ihres Programms testen.
Wenn Sie planen, ein ereignisbasiertes System zu testen, erleichtern Sie sich das Leben, wenn Sie das Abhängigkeitsinjektionsmuster verwenden und im Idealfall den ganzen Weg gehen und eine Inversion der Kontrolle verwenden (siehe Ссылка und Ссылка für Details dieser Muster)
(Danke an pc1oad1etter, um darauf hinzuweisen, dass ich die Links durcheinander gebracht habe)
Zuerst würde ich solche Ereignisse testen:
%Vor%Und dann entdeckte ich RhinoMocks . RhinoMocks ist ein Framework, das Mock-Objekte erstellt und Event-Tests abwickelt. Es kann auch für Ihre Verfahrensprüfung nützlich sein.
Beantworte meine eigene Frage hier, aber ich stieß auf einen Artikel, der das Problem erklärt und ein einfaches Beispiel durchläuft - Agile Benutzeroberflächenentwicklung . Der Code und die Bilder sind großartig, und hier ist ein Ausschnitt, der die Idee zeigt:
Agile Gurus wie Kent Beck und David Astels schlägt vor, die GUI zu erstellen indem wir die Ansichtsobjekte sehr dünn halten, und Testen der Schichten "unter dem Oberfläche. "Dieses" intelligente Objekt / dünn Ansicht "Modell ist analog zu den vertraute Dokumentenansicht und Client-Server-Paradigmen, sondern gilt zur Entwicklung individueller GUI Elemente. Trennung des Inhalts und Präsentation verbessert das Design des Codes, wodurch es modularer wird und testbar. Jede Komponente der Benutzeroberfläche ist als implementiert intelligentes Objekt, das den Anwendungsverhalten, das sein sollte getestet, aber kein GUI-Präsentationscode. Jedes Smart-Objekt hat ein entsprechendes Thin View-Klasse, die nur enthält generisches GUI-Verhalten. Mit diesem Design Modell, GUI-Gebäude wird zugänglich zu TDD.
Das Problem ist, dass "ereignisbasierte Programmierung" viel zu viel Logik mit den Ereignissen verknüpft. Die Art und Weise, wie ein solches System entworfen werden sollte, ist, dass es ein Subsystem geben sollte, das Ereignisse auslöst (und Sie können Tests schreiben, um sicherzustellen, dass diese Ereignisse in der richtigen Reihenfolge ausgelöst werden). Und es sollte ein anderes Subsystem geben, das sich nur damit beschäftigt, beispielsweise den Zustand eines Formulars zu verwalten. Und Sie können einen Komponententest schreiben, der überprüft, ob bei den richtigen Eingaben (dh Ereignisse, die ausgelöst werden) der Form-Zustand auf die richtigen Werte gesetzt wird.
Darüber hinaus ist der eigentliche Event-Handler, der von Komponente 1 ausgelöst wird und das Verhalten von Komponente 2 aufruft, nur ein Integrationstest, der manuell von einer QA-Person durchgeführt werden kann.
Ihre Frage enthält nicht Ihre Programmiersprache der Wahl, aber meine ist C #, also werde ich das Beispiel verwenden. Dies ist jedoch nur eine Verfeinerung gegenüber Gilligans, indem anonyme Delegierte verwendet werden, um Ihren Testcode einzubinden. Ich bin dafür, Tests so leserlich wie möglich zu machen, und für mich bedeutet das alles Testcode innerhalb der Testmethode;
%Vor% Die Klasse, die ich hier teste, implementiert die INotifyPropertyChanged
-Schnittstelle und daher sollte ein NotifyPropertyChanged
-Ereignis ausgelöst werden, wenn sich der Wert einer Eigenschaft geändert hat.
Ein Ansatz, den ich für prozeduralen Code als hilfreich empfunden habe, ist die Verwendung von TextTest. Es geht nicht so sehr um Komponententests, aber es hilft Ihnen, automatisierte Regressionstests durchzuführen. Die Idee ist, dass Sie Ihre Anwendung ein Protokoll schreiben und dann Texttest verwenden, um das Protokoll vor und nach Ihren Änderungen zu vergleichen.
Siehe häufig verlinkt Effektiv mit Legacy-Code arbeiten . Siehe die Abschnitte mit dem Titel "Meine Anwendung ist alle API-Aufrufe" und "Mein Projekt ist nicht objektorientiert. Wie führe ich sichere Änderungen durch?".
In der C / C ++ - Welt (meiner Erfahrung nach) ist es die beste Lösung in der Praxis, den Linker "Naht" zu verwenden und die Testdoppelwerte für alle von der zu testenden Funktion aufgerufenen Funktionen zu verknüpfen. Auf diese Weise ändern Sie den Legacy-Code nicht, aber Sie können ihn weiterhin isoliert testen.
Tags und Links unit-testing