Ich verbringe meine Zeit hauptsächlich damit, an automatisierten Tests von Win32- und .NET-Anwendungen zu arbeiten, die ungefähr 30% unserer Zeit zum Schreiben und 70% zum Warten benötigen. Wir haben nach Methoden gesucht, um die Wartungszeiten zu verkürzen, und sind bereits zu einer wiederverwendbaren Testbibliothek übergegangen, die die meisten Schlüsselkomponenten unserer Software abdeckt. Darüber hinaus haben wir einige Arbeiten im Gange, um unsere Bibliothek in einen Zustand zu versetzen, in dem wir stichwortbasierte Tests verwenden können .
Ich habe darüber nachgedacht, unsere Testbibliothek zu testen, aber ich frage mich, ob es sich lohnt. Ich bin ein starker Befürworter von Komponententests von Software, aber ich bin mir nicht sicher, wie ich mit Testcode umgehen soll.
Glauben Sie, dass automatisierte Gui-Testbibliotheken Unit-getestet werden sollten? Oder ist es nur Zeitverschwendung?
Zunächst fand ich es sehr nützlich, Unit-Test als "ausführbare Spezifikationen" anstatt als Tests zu betrachten. Ich schreibe auf, was mein Code tun soll und setze ihn dann um. Die meisten Vorteile, die ich aus dem Schreiben von Komponententests ziehen kann, sind, dass sie den Implementierungsprozess vorantreiben und mein Denken fokussieren. Die Tatsache, dass sie wiederverwendbar sind, um meinen Code zu testen, ist fast ein glücklicher Zufall.
Testing Tests scheint nur eine Möglichkeit, das Problem zu verschieben, anstatt es zu lösen. Wer wird die Tests testen, die die Tests testen? Der "Trick", den TDD verwendet, um sicherzustellen, dass Tests tatsächlich nützlich sind, besteht darin, dass sie zuerst fehlschlagen. Dies könnte etwas sein, das Sie auch hier verwenden können. Schreiben Sie den Test, sehen Sie, dass es fehlschlägt, und beheben Sie dann den Code.
Ich denke nicht, dass Sie Unit Tests testen sollten.
Aber, wenn Sie Ihre eigene Test-Bibliothek geschrieben haben, mit benutzerdefinierten Behauptungen, Tastatur-Controllern, Button-Testern oder was auch immer, dann ja. Sie sollten Komponententests schreiben, um zu verifizieren, dass alle wie vorgesehen funktionieren.
Die NUnit-Bibliothek wird beispielsweise als Einheit getestet.
Theoretisch ist Software und sollte daher Unit-getestet werden. Wenn Sie gerade Ihre eigene Unit Testing-Bibliothek laufen haben, sollten Sie die Unit-Test-Bibliothek testen, während Sie fortfahren.
Allerdings sollten die tatsächlichen Komponententests für Ihr primäres Softwaresystem niemals groß genug sein, um Komponententests zu benötigen. Wenn sie so komplex sind, dass sie Komponententests benötigen, müssen Sie Ihre Software gründlich umstrukturieren und die Einheitentests etwas vereinfachen.
Vielleicht möchten Sie einen Blick auf Wer testet die Tests .
Die kurze Antwort lautet, dass der Code die Tests testet und die Tests den Code testen.
Huh?
Testen von Atomuhren
Lassen Sie mich mit einer Analogie beginnen. Angenommen, du bist es Reisen mit einer Atomuhr. Woher weißt du, dass die Uhr ist? richtig kalibriert?Ein Weg ist es, deinen Nachbarn mit einer Atomuhr zu fragen (weil alle trägt eine herum) und vergleichen Sie die beiden. Wenn beide dasselbe berichten Zeit, dann haben Sie ein hohes Maß an Vertrauen, dass sie beide richtig sind.
Wenn sie anders sind, dann weißt du, dass das eine oder das andere falsch ist.
Wenn Sie in dieser Situation nur die Frage stellen, die Sie stellen, ist "Is my Gibst du die richtige Zeit? ", brauchst du dann wirklich eine dritte Uhr den zweiten Takt und einen vierten Takt zu testen, um den dritten zu testen? Nicht wenn alle. Stack Overflow vermieden!
IMPO: Es ist ein Kompromiss zwischen wie viel Zeit Sie haben und wie viel Qualität Sie haben möchten.
Es gibt wirklich keinen Grund, warum Sie Ihre Bibliothek nicht testen sollten. Einige Teile sind möglicherweise zu schwierig, um den Einheitentest richtig zu testen, aber die meisten davon können wahrscheinlich ohne besondere Probleme getestet werden.
Es ist tatsächlich wahrscheinlich besonders nützlich, diese Art von Code zu testen, da Sie erwarten, dass es sowohl zuverlässig als auch wiederverwendbar ist.
Die Tests testen den Code und der Code testet die Tests. Wenn Sie die gleiche Absicht auf zwei verschiedene Arten sagen (einmal in Tests und einmal im Code), ist die Wahrscheinlichkeit, dass beide falsch sind, sehr gering (sofern die Anforderungen nicht bereits falsch waren). Dies ist vergleichbar mit der von Buchhaltern verwendeten doppelten Buchführung. Siehe Ссылка
Vor kurzem wurde über dasselbe Thema in den Kommentaren von Ссылка
Über Ihre Frage sollten die GUI-Test-Bibliotheken getestet werden ... Wenn ich richtig verstanden habe, erstellen Sie Ihre eigene Test-Bibliothek, und Sie möchten wissen, ob Sie Ihre Test-Bibliothek testen sollten. Ja. Damit Sie sich darauf verlassen können, dass die Bibliothek Tests korrekt meldet, sollten Sie Tests durchführen, die sicherstellen, dass die Bibliothek keine False Positives oder False Negatives meldet. Unabhängig davon, ob die Tests Komponententests, Integrationstests oder Abnahmetests sind, sollten zumindest einige Tests durchgeführt werden.
Nach dem Schreiben des Codes ist es normalerweise zu spät, Schreibgeräte zu testen, weil dann der Code eher gekoppelt ist. Die Komponententests erzwingen eine stärkere Entkopplung des Codes, da sonst kleine Einheiten (eine Klasse oder eine eng verwandte Gruppe von Klassen) nicht isoliert getestet werden können.
Wenn der Code bereits geschrieben wurde, können Sie normalerweise nur Integrationstests und Akzeptanztests hinzufügen. Sie werden mit laufendem System ausgeführt, so dass Sie sichergehen können, dass die Funktionen richtig funktionieren, aber es ist schwieriger, jeden Winkelfall und Ausführungspfad abzudecken als bei Komponententests.
Wir verwenden im Allgemeinen diese Faustregeln:
1) Der gesamte Produktcode enthält sowohl Komponententests (die so angeordnet sind, dass sie eng mit den Produktcodeklassen und -funktionen übereinstimmen) als auch separate Funktionstests (geordnet nach den für den Benutzer sichtbaren Funktionen)
2) Schreiben Sie keine Tests für Code von Drittanbietern, z. B. .NET-Steuerelemente oder Bibliotheken von Drittanbietern. Die Ausnahme ist, wenn Sie wissen, dass sie einen Fehler enthalten, an dem Sie arbeiten. Ein Regressionstest dafür (der fehlschlägt, wenn der 3rd-Party-Fehler verschwindet) wird Sie warnen, wenn Upgrades auf Ihre 3rd-Party-Bibliotheken den Fehler beheben, was bedeutet, dass Sie Ihre Problemumgehungen entfernen können.
3) Komponententests und Funktionstests werden selbst nie direkt getestet - APART von der Verwendung des TDD-Verfahrens des Schreibens des Tests vor dem Produktcode, dann Ausführen des Tests, um zu beobachten, wie es versagt. Wenn Sie dies nicht tun, werden Sie erstaunt daran sein, wie einfach es ist, versehentlich Tests zu schreiben, die immer bestehen. Idealerweise würden Sie dann Ihren Produktcode Schritt für Schritt implementieren und die Tests nach jeder Änderung ausführen, um zu sehen, dass jede einzelne Assertion in Ihrem Test fehlschlägt, dann implementiert wird und mit der Übergabe beginnt. Dann werden Sie sehen, dass die nächste Behauptung fehlschlägt. Auf diese Weise werden Ihre Tests getestet, aber nur während der Produktcode geschrieben wird.
4) Wenn wir Code aus unserer Unit oder aus funktionalen Tests herausfiltern - indem wir eine Testbibliothek erstellen, die in vielen Tests verwendet wird, dann testen wir dies alles einzeln.
Das hat uns sehr gut gedient. Wir scheinen uns immer zu 100% an diese Regeln gehalten zu haben, und wir sind sehr glücklich mit unserem Arrangement.
Kent Becks Buch "Test-Driven Development: By Example" hat ein Beispiel für die testgetriebene Entwicklung eines Unit-Test-Frameworks, so dass es durchaus möglich ist, Ihre Tests zu testen.
Ich habe nicht mit GUIs oder .NET gearbeitet, aber welche Bedenken haben Sie bezüglich Ihrer Komponententests?
Haben Sie Angst, dass der Zielcode bei ordnungsgemäßer Ausführung als falsch beschrieben wird? Ich nehme an, das ist eine Möglichkeit, aber Sie könnten wahrscheinlich erkennen, wenn das passiert.
Oder sind Sie besorgt, dass der Zielcode möglicherweise richtig funktioniert, auch wenn dies nicht der Fall ist? Wenn Sie sich darüber Sorgen machen, können Mutationstests das sein, wonach Sie suchen. Mutationstests ändern Teile des zu testenden Codes, um festzustellen, ob diese Änderungen dazu führen, dass Tests fehlschlagen. Wenn dies nicht der Fall ist, wird entweder der Code nicht ausgeführt oder die Ergebnisse dieses Codes werden nicht getestet.
Wenn auf Ihrem System keine Mutationstestsoftware verfügbar ist, können Sie die Mutation manuell durchführen, indem Sie den Zielcode selbst sabotieren und feststellen, ob dadurch die Komponententests fehlschlagen.
Wenn Sie eine Suite von Komponententestprodukten erstellen, die nicht an eine bestimmte Anwendung gebunden sind, sollten Sie vielleicht eine triviale Anwendung erstellen, mit der Sie Ihre Testsoftware ausführen und sicherstellen können, dass die erwarteten Fehler und Erfolge auftreten.
Ein Problem mit Mutationstests ist, dass es nicht sicherstellt, dass die Tests alle potenziellen Szenarien abdecken, denen ein Programm begegnen könnte. Stattdessen wird nur sichergestellt, dass alle vom Zielcode erwarteten Szenarien getestet werden.
Ja, Ihre GUI-Testbibliotheken sollten getestet werden.
Wenn Ihre Bibliothek beispielsweise eine Check -Methode zum Überprüfen des Inhalts eines Gitters gegen ein zweidimensionales Array bereitstellt, möchten Sie sicher sein, dass sie wie beabsichtigt funktioniert.
Andernfalls sind Ihre komplexeren Testfälle, die Geschäftsprozesse testen, in denen ein Grid bestimmte Daten empfangen muss, möglicherweise unzuverlässig. Wenn ein Fehler in Ihrer Check -Methode falsche negative Ergebnisse ergibt, werden Sie das Problem schnell finden. Wenn es jedoch falsch positive Ergebnisse produziert, sind Sie auf dem Weg zu großen Kopfschmerzen.
So testen Sie Ihre CheckGrid -Methode:
Sie sollten das folgende dunit-Beispiel für die meisten Frameworks ändern können, um zu testen, ob CheckGrid Fehler korrekt erkennt:
%Vor%Ich wiederhole: Ihre GUI-Testbibliotheken sollten getestet werden; und der Trick ist - wie machst du das so effektiv?
Der TDD-Prozess empfiehlt Ihnen, zuerst herauszufinden, wie Sie testen eine neue Funktionalität vor implementieren möchten. Der Grund ist, dass, wenn Sie es nicht tun, Sie oft finden, dass Sie sich den Kopf kratzen, wie Sie verifizieren werden, dass es funktioniert. Es ist äußerst schwierig, Testfälle auf bestehende Implementierungen umzurüsten.
Eine Sache, die du gesagt hast, stört mich ein wenig ... du sagtest, dass es "70% (deiner Zeit) braucht, um (deine Tests) aufrechtzuerhalten"
Das hört sich für mich etwas falsch an, weil Ihre Tests idealerweise einfach sein sollten und sich nur ändern sollten, wenn sich Ihre Schnittstellen oder Regeln ändern.
Ich habe Sie vielleicht missverstanden, aber ich habe den Eindruck, dass Sie keinen "Produktionscode" schreiben. Andernfalls sollten Sie mehr Kontrolle über den Wechselzyklus zwischen Testcode und Produktionscode haben, um Ihr Problem zu reduzieren.
Einige Vorschläge:
Persönlich teste ich meine Automatisierungsbibliotheken nicht Unit-Test, sondern führe sie gegen eine modifizierte Version der Baseline aus, um sicherzustellen, dass alle Checkpoints funktionieren. Das Prinzip ist, dass meine Automatisierung hauptsächlich für Regressionstests, z.B. dass die Ergebnisse für den aktuellen Lauf dieselben sind wie die erwarteten Ergebnisse (dies entspricht normalerweise den Ergebnissen des letzten Laufs). Durch Ausführen der Tests gegen einen geeignet modifizierten Satz erwarteter Ergebnisse sollten alle Tests fehlschlagen. Wenn sie nicht haben Sie einen Fehler in Ihrer Testsuite. Dies ist ein Konzept, das sich aus Mutationstests entlehnt hat, die sich gut für die Überprüfung von GUI-Automatisierungssuiten eignen.
Aus Ihrer Frage kann ich verstehen, dass Sie ein Keyword Driven Framework für die Durchführung von Automatisierungstests erstellen. In diesem Fall wird immer empfohlen, einige White-Box-Tests für die allgemeinen und GUI-Dienstprogrammfunktionen durchzuführen. Da Sie daran interessiert sind, jede GUI-Testfunktion in Ihren Bibliotheken zu testen, gehen Sie bitte darauf ein. Testen ist immer gut. Es ist keine Zeitverschwendung, ich würde es als einen "Mehrwert" für Ihr Framework sehen.
Sie haben auch bereits den Umgang mit Testcode erwähnt. Wenn Sie den Testansatz meinen, gruppieren Sie bitte verschiedene Funktionen / Module, die ähnliche Arbeiten ausführen, zB: GUI Element Validierung (Präsenz), GUI Element Eingabe, GUI Element lesen. Gruppieren Sie für verschiedene Elementtypen und führen Sie für jede Gruppe einen Typ-Unit-Test-Ansatz durch. Es wäre einfacher für Sie, die Tests zu verfolgen. Prost!
Ich würde vorschlagen, den Test zu testen ist eine gute Idee und etwas, was getan werden muss. Stellen Sie nur sicher, dass das, was Sie zum Testen Ihrer App erstellen, nicht komplexer ist als die App selbst. Wie bereits erwähnt, ist TDD ein guter Ansatz, selbst wenn automatische Funktionstests durchgeführt werden (ich persönlich würde es nicht so machen, aber es ist trotzdem ein guter Ansatz). Unit-Test Sie Test-Code ist ein guter Ansatz. IMHO, wenn Sie GUI-Tests automatisieren, gehen Sie einfach weiter mit manuellen Tests zur Verfügung (Sie sollten Schritte, rohe Szenarien, erwartete Ergebnisse und so weiter), stellen Sie sicher, dass sie bestehen. Für andere Tests, die Sie erstellen könnten und die noch nicht manuell gescriptet wurden, testen Sie sie im Unit-Test und folgen einem TDD-Ansatz. (Wenn Sie Zeit haben, können Sie die anderen Geräte testen). Schließlich ist Keyword-getrieben, IMO, der beste Ansatz, dem Sie folgen könnten, weil es Ihnen den flexibelsten Ansatz gibt.
Vielleicht möchten Sie ein Framework für Mutationstests erkunden (wenn Sie mit Java arbeiten: PIT Mutation Testing ). Eine weitere Möglichkeit, die Qualität Ihrer Komponententests zu beurteilen, besteht darin, sich Berichte anzusehen, die von Tools wie SonarQube bereitgestellt werden. Die Berichte enthalten verschiedene Abdeckungsmetriken .
Tags und Links unit-testing automated-tests