Wie kann ich eine GUI testen?

154

Die Berechnungen in meinem Code sind gut getestet, aber da es so viel GUI-Code gibt, ist meine gesamte Codeabdeckung geringer als ich möchte. Gibt es Richtlinien zum Testen von GUI-Code? Macht es überhaupt Sinn?

Zum Beispiel gibt es Grafiken in meiner App. Ich konnte nicht herausfinden, wie das Testen der Diagramme automatisiert werden kann. Es braucht ein menschliches Auge, AFAIK, um zu überprüfen, ob die Grafik korrekt ist.

(Ich benutze Java Swing)

Steve McLeod
quelle
1
Es gibt einen großartigen Artikel über verschiedene GUI-Architekturen von Martin Fowler ( martinfowler.com/eaaDev/uiArchs.html ). Es beschreibt Kompromisse bei der GUI-Architektur in Bezug auf Unit-Tests.
Roman Hwang
1
Heutzutage sollte diese Frage besser auf programmers.stackexchange.com gestellt werden (und ist bei Stack Overflow wahrscheinlich nicht zum Thema, da sie zu breit ist), aber alte Fragen können nicht migriert werden. Die Frage, ob es hierher gehört, bleibt ein interessantes und schwieriges Problem.
Mark Amery
1
Es wäre großartig, ein Beispiel mit einem GUI-Code und JUnit zu haben.
Witold Kaczurba
1
Ich würde sagen, entspann dich und kümmere dich nicht darum. Der Aufwand für Unit-Tests erweist sich nicht immer als netto produktiv.
Codeulike
Alte Frage noch, Sie können den Fluss in der GUI mit Jubula
Abi

Antworten:

68

Designs wie MVP und MVC versuchen normalerweise, so viel Logik wie möglich aus der tatsächlichen GUI zu abstrahieren. Ein sehr beliebter Artikel dazu ist "The Humble Dialog Box" von Michael Feathers. Persönlich habe ich gemischte Erfahrungen mit dem Versuch gemacht, Logik aus der Benutzeroberfläche zu entfernen - manchmal hat es sehr gut funktioniert, und manchmal war es mehr Ärger als es wert ist. Es liegt jedoch etwas außerhalb meines Fachgebiets.

Jon Skeet
quelle
??? "Manchmal hat es sehr gut funktioniert, und manchmal war es mehr Ärger als es wert ist." Sehr seltsam, weil die meisten neuen Sprachen eher MVC-orientiert sind ... was Logik aus der GUI (Model-Visual) ist ...
Patrick Desjardins
14
Die Präsentationslogik befindet sich jedoch in der GUI. Manchmal ist das alles andere als trivial
Andrea
16
Spiegel: Das bescheidene Dialogfeld
c24w
Martin Fowlers Behandlung des Konzepts (falls Ihr Netzwerk wie meins archive.org filtert): martinfowler.com/eaaDev/uiArchs.html#HumbleView
Christopher Berman
@ c24w danke für das Ziehen dieses Spiegels, du bist der echte MVP :)
John Baker
38

Die Antwort ist natürlich, MVC zu verwenden und so viel Logik wie möglich aus der GUI zu entfernen.

Davon abgesehen hörte ich vor langer Zeit von einem Kollegen, dass SGI, als es OpenGL auf neue Hardware portierte, eine Reihe von Komponententests durchführte, bei denen eine Reihe von Grundelementen auf den Bildschirm gezeichnet und dann eine MD5-Summe des Bildpuffers berechnet wurden. Dieser Wert könnte dann mit bekannten guten Hashwerten verglichen werden, um schnell festzustellen, ob die API pro Pixel genau ist.

Dicroce
quelle
3
Ich mag diesen Ansatz. Das Einrichten und Warten ist umständlich, bietet mir jedoch die erforderlichen Regressionstestfunktionen.
Steve McLeod
7
danatel du hast den Punkt verpasst. OpenGL ist eine pixelgenaue Grafik-Rendering-API. GUI-Anwendungsframeworks wie Qt werden stark vom Systemchrom abhängig sein, daher ist das Hashing des Frame-Puffers kein guter Ansatz.
Bob Somers
1
Ein MD5? Was hat ein kryptografischer Hash damit zu tun? Wie geht es um Sicherheit? Ein Hash, OK, es ist eine großartige Idee für pixelgenaue Grafiken, aber ein kryptografischer Hash? Sie können schnellere Hashes verwenden, die nicht kryptografisch sind und deren Kollisionswahrscheinlichkeit vernachlässigbar ist. Sind Sie sicher, dass es ein kryptografischer Hash war und nicht einfach ein Hash? (
Darüber
24
@ SyntaxT3rr0r: Welche Hash-Funktion würden Sie für diese Art von nicht sicherheitsrelevanten Anwendungen empfehlen, und welchen Leistungsgewinn kann man im Vergleich zu MD5 erwarten?
Lèse Majesté
1
Ihre Antwort bedeutet "Entwerfen Sie niemals Ihre GUI und testen Sie sie daher nicht". Cool.
Dims
10

Sie können versuchen, UISpec4J ist eine Open Source-Funktions- und / oder Unit-Test-Bibliothek für Swing-basierte Java-Anwendungen ...

CMS
quelle
2
Ich habe ungefähr einen Monat lang damit begonnen, UISpec4J zu verwenden, um Anforderungsvalidierungstests auf Java Swing-GUIs durchzuführen. Ich habe es bisher sehr gemocht.
Bassam
github.com/UISpec4J/UISpec4J gibt an, dass Ihr Link die offizielle Website ist, aber für mich sieht er nicht so offiziell aus. Alles was ich sehe ist ein Blog über Vlogging
Lucidbrot
7

Es gibt Selenium RC , das das Testen einer webbasierten Benutzeroberfläche automatisiert. Es werden Aktionen aufgezeichnet und wiedergegeben. Sie müssen noch die Interaktionen mit Ihrer Benutzeroberfläche durchgehen, damit dies nicht zur Abdeckung beiträgt, sondern für automatisierte Builds verwendet werden kann.

David Robbins
quelle
7

Sie können versuchen, mit Cucumber und Swinger funktionale Abnahmetests in einfachem Englisch für Swing-GUI-Anwendungen zu schreiben. Swinger verwendet die Jemmy-Bibliothek von Netbeans unter der Haube, um die App zu steuern.

Mit Cucumber können Sie Tests wie folgt schreiben:

 Scenario: Dialog manipulation
    Given the frame "SwingSet" is visible
    When I click the menu "File/About"
    Then I should see the dialog "About Swing!"
    When I click the button "OK"
    Then I should not see the dialog "About Swing!"

Schauen Sie sich diese Swinger-Video-Demo an, um sie in Aktion zu sehen.

Dema
quelle
6

Hier einige Tipps:

Versuchen Sie, so viel Code wie möglich von der GUI zu entfernen (Controller und Modellobjekt), damit Sie sie ohne die GUI testen können.

Für die Grafik sollten Sie den Wert testen, den Sie dem Code geben, der die Grafik generiert.

Patrick Desjardins
quelle
6

Testen ist eine Kunstform. Ich bin damit einverstanden, dass die Logik der GUI so weit wie möglich entfernt wird. Dort können wir uns dann auf unsere Unit-Tests konzentrieren. Wie bei allem anderen geht es beim Testen darum, das Risiko zu reduzieren. Sie müssen nicht immer alles testen, aber oft ist es das Beste, die verschiedenen Tests in verschiedenen Bereichen aufzubrechen.

Die andere Frage ist, was Sie wirklich versuchen, auf der UI-Ebene zu testen. UI-Tests sind die teuersten Tests, da die Erstellung, Wartung und Sprödigkeit normalerweise länger dauert. Wenn Sie die Logik testen, um zu wissen, dass die Koordinaten korrekt sind, bevor Sie versuchen, die Linie zu zeichnen, was testen Sie speziell? Wenn Sie ein Diagramm mit einer roten Linie testen möchten, wird gezeichnet. Können Sie ihm vorgegebene Koordinaten geben und testen, ob bestimmte Pixel rot sind oder nicht? Wie oben vorgeschlagen, funktionieren Bitmap-Vergleiche. Selenium, aber mein Hauptaugenmerk liegt nicht darauf, die GUI zu übertesten, sondern die Logik zu testen, die beim Erstellen der Benutzeroberfläche hilft, und sich dann darauf zu konzentrieren, welcher Teil der Benutzeroberfläche kaputt geht oder verdächtig ist, und eine Handvoll Tests zu fokussieren Dort.

Charles Smith
quelle
3

Sie können JFCUnit verwenden , um Ihre GUI zu testen, aber Grafiken können schwieriger sein. Ich habe bei einigen Gelegenheiten Schnappschüsse von meiner GUI gemacht und diese automatisch mit einer früheren Version verglichen. Dies bietet zwar keinen tatsächlichen Test, warnt Sie jedoch, wenn ein automatischer Build nicht die erwartete Ausgabe erzeugt.

Steve Moyer
quelle
3

Aus Ihrer Frage geht hervor, dass Sie nach einer automatisierten Methode suchen, um Ihr GUI-Verhalten im Detail zu testen. Das Beispiel, das Sie geben, ist das Testen, ob eine Kurve tatsächlich korrekt gezeichnet wurde.

Unit-Test-Frameworks bieten eine Möglichkeit, automatisierte Tests durchzuführen. Ich denke, die Art von Tests, die Sie durchführen möchten, sind komplizierte Integrationstests, die das korrekte Verhalten einer Vielzahl von Klassen überprüfen, darunter die Klassen Ihres GUI-Toolkits / Ihrer GUI-Bibliothek, die Sie verwenden sollte nicht testen wollen.

Ihre Optionen hängen stark davon ab, welche Plattformen / Toolkits / Frameworks Sie verwenden: Beispielsweise kann eine Anwendung, die Qt als GUI-Framework verwendet, Squish verwenden, um ihre Tests zu automatisieren. Sie überprüfen die Ergebnisse Ihrer Tests einmal und nachfolgende automatisch ausgeführte Tests vergleichen die Ergebnisse mit den überprüften Ergebnissen.

andreas buykx
quelle
2

Fensterlecker für Swing & Ajax

robi-y
quelle
2

Mein Ansatz für GUI-Tests entwickelt sich weiter, ebenso wie der Branchenkonsens. Aber ich denke, einige Schlüsseltechniken tauchen auf.

Ich verwende je nach Situation eine oder mehrere dieser Techniken (z. B. welche Art von GUI es ist, wie schnell sie erstellt werden muss, wer der Endbenutzer sein wird usw.).

  1. Manuelle Prüfung. Während der Arbeit am Code wird immer die GUI ausgeführt, und Sie müssen sicherstellen, dass sie mit dem Code synchronisiert ist. Sie testen den Teil, an dem Sie arbeiten, manuell und erneut, während Sie daran arbeiten, und wechseln zwischen dem Code und der laufenden Anwendung. Jedes Mal, wenn Sie eine wichtige Arbeit erledigen, geben Sie dem gesamten Bildschirm oder Bereich der Anwendung einen Gesamttest, um sicherzustellen, dass keine Regressionen vorliegen.

  2. Unit Testing. Sie schreiben Tests für Funktionen oder kleine Einheiten des GUI-Verhaltens. Beispielsweise müssen Ihre Diagramme möglicherweise verschiedene Farbtöne basierend auf einer Grundfarbe berechnen. Sie können diese Berechnung in eine Funktion extrahieren und einen Komponententest dafür schreiben. Sie können in der GUI nach einer solchen Logik suchen (insbesondere nach wiederverwendbarer Logik) und diese in diskrete Funktionen extrahieren, die einfacher in Einheiten getestet werden können. Selbst komplexes Verhalten kann auf diese Weise extrahiert und getestet werden. Beispielsweise kann eine Folge von Schritten in einem Assistenten in eine Funktion extrahiert werden, und ein Komponententest kann überprüfen, ob bei einer Eingabe der richtige Schritt zurückgegeben wird.

  3. Komponenten-Explorer. Sie erstellen einen "Explorer" -Bildschirm, dessen einzige Aufgabe darin besteht, alle wiederverwendbaren Komponenten Ihrer GUI anzuzeigen. Auf diesem Bildschirm können Sie schnell und einfach visuell überprüfen, ob jede Komponente das richtige Erscheinungsbild aufweist. Der Komponenten-Explorer ist effizienter als das manuelle Durchlaufen Ihrer gesamten Anwendung, da A) Sie jede Komponente nur einmal überprüfen müssen und B) Sie nicht tief in die Anwendung navigieren müssen, um die Komponente zu sehen, sondern nur anzeigen und Überprüfen Sie es sofort.

  4. Automatisierungstests. Sie schreiben einen Test, der mit dem Bildschirm oder der Komponente interagiert, Mausklicks, Dateneingabe usw. simuliert und bestätigt, dass die Anwendung bei diesen Manipulationen ordnungsgemäß funktioniert. Dies kann als zusätzlicher Sicherungstest nützlich sein, um potenzielle Fehler zu erfassen, die bei Ihren anderen Tests möglicherweise übersehen werden. Ich neige dazu, Automatisierungstests für die Teile der GUI zu reservieren, die am anfälligsten für Brüche sind und / oder äußerst kritisch sind. Teile, bei denen ich so früh wie möglich wissen möchte, ob etwas kaputt ist. Dies kann hochkomplexe interaktive Komponenten umfassen, die anfällig für Unterbrechungen oder wichtige Hauptbildschirme sind.

  5. Diff / Snapshot-Test. Sie schreiben einen Test, der die Ausgabe einfach als Screenshot oder als HTML-Code erfasst und mit der vorherigen Ausgabe vergleicht. Auf diese Weise werden Sie benachrichtigt, wenn sich die Ausgabe ändert. Diff-Tests können hilfreich sein, wenn der visuelle Aspekt Ihrer GUI komplex ist und / oder Änderungen unterworfen ist. In diesem Fall möchten Sie schnelles und visuelles Feedback darüber, welche Auswirkungen eine bestimmte Änderung auf die GUI insgesamt hat.

Anstatt jede mögliche Art von Test hartnäckig anzuwenden, ziehe ich es vor, die Testtechnik basierend auf der Art der Dinge, an denen ich arbeite, auszuwählen. In einem Fall extrahiere ich eine einfache Funktion und teste sie in einer Einheit. In einem anderen Fall füge ich dem Komponenten-Explorer usw. eine Komponente hinzu. Dies hängt von der jeweiligen Situation ab.

Ich habe nicht festgestellt, dass die Codeabdeckung eine sehr nützliche Metrik ist, aber andere haben möglicherweise eine Verwendung dafür gefunden.

Ich denke, die erste Maßnahme ist die Anzahl und Schwere der Fehler. Ihre erste Priorität ist wahrscheinlich eine Anwendung, die ordnungsgemäß funktioniert. Wenn die Anwendung ordnungsgemäß funktioniert, sollten nur wenige oder keine Fehler auftreten. Wenn es viele oder schwerwiegende Fehler gibt, testen Sie vermutlich entweder nicht oder Ihre Tests sind nicht effektiv.

Neben der Reduzierung von Fehlern gibt es noch andere Maßnahmen wie Leistung, Benutzerfreundlichkeit, Zugänglichkeit, Wartbarkeit, Erweiterbarkeit usw. Diese unterscheiden sich je nach Art der von Ihnen erstellten Anwendung, dem Unternehmen, dem Endbenutzer usw.

Dies alles basiert auf meinen persönlichen Erfahrungen und Recherchen sowie auf einem großartigen Bericht über UI-Tests von Ham Vocke .

Jonathan
quelle
1

Soweit ich weiß, ist dies ziemlich kompliziert und hängt wirklich von der Sprache ab - zahlreiche Sprachen haben ihre eigene Art, die GUI zu testen, aber wenn Sie die GUI wirklich testen müssen (im Gegensatz zur Modell / GUI-Interaktion), müssen Sie dies häufig tun simulieren Sie einen tatsächlichen Benutzer, der auf Schaltflächen klickt. Das in Eclipse verwendete SWT-Framework bietet beispielsweise SWTBot , JFCUnit wurde bereits erwähnt, Mozilla hat eine eigene Art, dies in XUL zu simulieren (und nach dem, was ich in ihren Blogs gelesen habe, scheinen diese Tests ziemlich spröde zu sein).

Manchmal müssen Sie einen Screenshot machen und auf pixelgenaues Rendern testen (ich glaube, Mozilla überprüft dies auf korrekt gerenderte Seiten) - dies erfordert eine längere Einrichtung, ist aber möglicherweise das, was Sie für die Grafiken benötigen. Auf diese Weise müssen Sie beim Aktualisieren Ihres Codes und bei einer Testpause das Bild manuell überprüfen, ob der Fehler tatsächlich aufgetreten ist, oder Sie haben den Code für das Rendern von Grafiken verbessert, um hübschere Grafiken zu generieren, und müssen die Screenshots aktualisieren.

Kim Sullivan
quelle
0

Wenn Sie Swing verwenden, ist FEST-Swing nützlich, um Ihre GUI zu steuern und Behauptungen zu testen. Es macht es ziemlich einfach, Dinge wie "Wenn ich auf Schaltfläche A klicke, sollte Dialog B angezeigt werden" oder "Wenn ich Option 2 aus der Dropdown-Liste auswähle, sollten alle Kontrollkästchen deaktiviert werden" zu testen. .

Das von Ihnen erwähnte Diagrammszenario ist nicht so einfach zu testen. Es ist ziemlich einfach, Codeabdeckung für GUI-Komponenten zu erhalten, indem Sie sie erstellen und anzeigen (und sie möglicherweise mit FEST steuern). Es ist jedoch schwierig, aussagekräftige Aussagen zu machen (und die Codeabdeckung ohne aussagekräftige Aussagen ist eine Übung zur Selbsttäuschung). Wie testen Sie, ob das Diagramm nicht verkehrt herum oder zu klein gezeichnet wurde?

Ich denke, Sie müssen nur akzeptieren, dass einige Aspekte von GUIs nicht effektiv durch automatisierte Komponententests getestet werden können und dass Sie sie auf andere Weise testen müssen.

Dan Dyer
quelle
0

Es ist nicht Ihre Aufgabe, die GUI-Bibliothek zu testen. Sie können also der Verantwortung ausweichen, zu überprüfen, was tatsächlich auf dem Bildschirm gezeichnet wird, und stattdessen die Eigenschaften der Widgets überprüfen, indem Sie der Bibliothek vertrauen, dass sie genau das darstellen, was gezeichnet wird.

ivan_pozdeev
quelle