Wie testet eine Einheit Codeabschnitte, die prozedural oder ereignisbasiert sind?

8

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.

    
pc1oad1etter 16.09.2008, 14:41
quelle

7 Antworten

5

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)

    
David Arno 16.09.2008, 14:55
quelle
2

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.

    
Gilligan 16.09.2008 14:49
quelle
2

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.

    
pc1oad1etter 20.09.2008 05:40
quelle
1

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.

    
Joel Martinez 16.09.2008 14:46
quelle
1

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.

    
Kjetil Klaussen 22.12.2008 14:20
quelle
0

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.

    
Emily 16.09.2008 14:50
quelle
0

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.

    
Joe Schneider 17.09.2008 17:58
quelle

Tags und Links