Einführung
Sie haben sicher schon von Regressions- und Akzeptanztests gehört. Aber wissen Sie, wie viel tatsächlich in einem Projekt für Akzeptanztests ausgegeben wird?
Mit Hilfe eines Zeiterfassungssystems wie TMetric können wir darauf schnell eine Antwort bekommen.
In unserem Projekt, Akzeptanztests eine Desktop-Anwendung von rund 100 Baugruppen dauerte mehr als 2 Personenwochen. Die größten Schwierigkeiten hatten neue QA-Spezialisten, die die Anwendung nicht gut kannten. Im Vergleich zu erfahreneren QA-Spezialisten verbrachten sie viel mehr Zeit mit jedem Testfall.
Das Unangenehmste war meiner Meinung nach jedoch – wenn vor der Freigabe kritische Fehler gefunden werden, muss der Abnahmetest erneut durchgeführt werden nachdem diese Fehler behoben wurden.
Schriftliche Unit-Tests halfen ein wenig, aber sie reduzierten immer noch größtenteils die Zeit, die für Regressionstests aufgewendet wurde. Als der Umfang der manuellen Tests ein kritisches Niveau erreichte, begannen wir damit, uns in Richtung Automatisierung zu bewegen.
Rendite
Bevor wir automatisierte UI-Tests schrieben, mussten wir bewerten, wie profitabel unsere Investitionen sind. Wir taten dies mit Hilfe von ROI (Return On Investment https://en.wikipedia.org/wiki/Return_on_investment)
Die Berechnung des ROI von UI-Tests wurde auch zu einer interessanten Aufgabe mit mehreren unbekannten Variablen:
ROI =Gewinn / Ausgaben
oder
ROI =(Gewinn – Ausgaben) / Ausgaben
Zu diesem Zeitpunkt brauchten wir einen kleinen Prototypen, der uns helfen würde, alle notwendigen Kosten abzuschätzen. Es zeigte sehr merkwürdige Ergebnisse:Die Durchführung von Akzeptanztests dauert ungefähr so lange wie die Automatisierung dieses Prozesses. Zuerst sahen diese Informationen fragwürdig aus, aber als wir weiter nachforschten, wurden die Gründe klar:
- Neue QA-Spezialisten könnten die in Testfällen beschriebenen Schritte nur begrenzt verstehen. In diesem Fall werden einige Personen an Abnahmetests beteiligt sein, um die Situation besser zu verstehen. Hier sollten wir auch die Frage berücksichtigen, wie relevant die Informationen sind, die wir über Umgebungseinstellungen und -anforderungen haben.
- Manchmal verbringen Personen, die an Akzeptanztests beteiligt sind, Zeit damit, technische Dokumentation zu lernen.
- Die App selbst interagiert mit einer bestimmten Reihe von Diensten. Wenn einer von ihnen nicht verfügbar ist, verbringen die weniger erfahrenen QA-Spezialisten Zeit damit, Fehler zu beschreiben, die die Entwickler ihrerseits untersuchen werden. Infolgedessen wird Zeit verschwendet, weil der erforderliche Dienst nach einem Stromausfall/Hardware-Update/Computerneustart einfach nicht richtig lief.
- Die Computer der QA-Tester sind nicht sehr leistungsfähig. Wenn keine SSD vorhanden ist, merkt man das schon beim Einbau. Auch wenn die App stark ausgelastet ist, ist es möglich, dass eine langsame Auslagerungsdatei verwendet wird.
- Um ehrlich zu sein, haben wir uns hinreißen lassen und vergessen, dass wir mit Automatisierung arbeiten. Übrigens, hast du den Youtube-Tab in deinem Browser geschlossen?
Kommen wir nun zurück zum ROI. Der Einfachheit halber wurden die Berechnungen nach Zeit durchgeführt. Lassen Sie uns den Gewinn als Einsparungen bei manuellen Tests berechnen, und der betrachtete Zeitraum ist ein Jahr:
Gewinn =(X – Y) * N =(60 – 1) * 8 =472 Tage
X – Zeitaufwand für manuelle Tests (60 Tage)
Y – Zeitaufwand für die Durchführung automatisierter Tests (1 Tag)
N – Zeitaufwand für die Abnahme
Als Nächstes sehen wir uns die Ausgaben an:
Ausgaben =A + B + C + D + E + F =0 + 10 + 5 + 50 + 7 + 8 =80
A – Die Kosten für die Lizenz des Automatisierungstools. In unserem Fall wurde ein kostenloses Tool verwendet.
B – Schulung eines QA-Spezialisten (10 Tage)
C – Vorbereitung der Infrastruktur (5 Tage)
D – Entwicklung von Tests (50 Tage)
E – Durchführen von Tests und Beschreiben von dabei entdeckten Fehlern (7 Tage)
F – Testwartung (8 Tage)
Insgesamt:
ROI =Gewinn / Ausgaben =472 / 80 =5,9
Natürlich sind einige der Aspekte hier geschätzt. Um unsere eigenen Berechnungen zu bewerten, haben wir einige Zeit damit verbracht, die Möglichkeiten zu untersuchen, die kostenpflichtige Lösungen und verschiedene ROI-Rechner bieten. Damit haben wir den durchschnittlichen ROI-Wert von 2 oder 3 errechnet, was ein tolles Ergebnis ist.
Bestehende Frameworks
Nach den organisatorischen Fragen konzentrieren wir uns auf Fragen der technischen Art. Die wichtigste davon war die Auswahl eines Frameworks zur Automatisierung des Testens unserer Desktop-Anwendung. Wir hatten die folgenden Anforderungen basierend auf den Funktionen unseres Projekts:
- Tests werden entwickelt und auf Windows-Rechnern ausgeführt
- Das Framework sollte für das Testen von Desktop-Anwendungen angepasst werden
- UI-Tests können in den CI-Prozess integriert werden. Wir haben Jenkins bereits verwendet, daher war es hier vorzuziehen
- Die Möglichkeit, Tests in einer benutzerfreundlichen IDE zu schreiben – sie muss über Syntaxhervorhebung, Testskriptnavigation und Codevervollständigung im IntelliSense-Stil verfügen
- Minimale Ausgaben für QA-Schulungen. Aus bestimmten Gründen wollten unsere QA-Spezialisten keine Tests in Brainfuck schreiben
- Eine Community auf Stack Overflow, MSDN usw. ist vorzuziehen
Test abgeschlossen
Diese Plattform gefiel uns zunächst aufgrund ihrer Reife, was uns technisch Hoffnungen machte.
Als erstes stießen wir auf eine instabile und ziemlich veraltete IDE. Die Umgebung handhabte die Syntaxhervorhebung mehr oder weniger anständig, aber es gab erhebliche Probleme mit der Navigation (Zur Definition), der Suche und der automatischen Codevervollständigung:Diese Funktionalität funktionierte in etwa 60 % der Fälle überhaupt nicht. Der eingebaute Rekorder und ein Inspect-Analog funktionierten einwandfrei. Am Ende hat uns die IDE unangenehm überrascht, als sie anfing, Argumente an die Anwendung weiterzugeben. Dies führte erwartungsgemäß zu Fehlern in der Leistung der Anwendung:
--no-sandbox program files (x86)\smartbear\testcomplete12\x64\bin\Extensions\tcCrExtension\tcCEFHost.dll;application/x-testcomplete12-0-chrome-browser-agent
In dieser Phase haben wir den Support von TestComplete in die Situation einbezogen, um Zeit zu sparen und die Qualität des technischen Supports zu bewerten, bevor wir möglicherweise eine Lizenz kaufen. Nach ein paar Briefen an den technischen Support bekamen wir eine Antwort – wir sollten die an die Anwendung übergebenen Argumente ignorieren. Seltsam, nicht wahr? Bei weiteren Untersuchungen haben wir herausgefunden, dass diese Argumente erforderlich sind, um Anwendungen zu testen, die CEF verwenden. In unserem nächsten Brief erklärten wir, dass wir CEF verwenden, und wurden von den Support-Spezialisten aufgefordert, die Argumente nicht zu ignorieren. Als wir nach der genauen Verwendung fragten, änderte sich die Antwort wieder in „Ignoriere die Argumente“.
Wir verließen unser Gespräch mit dem technischen Support und wandten uns (ohne große Hoffnung) der Dokumentation der IDE zu. Es enthielt weitere Informationen, aber wir fanden nichts zu dem betreffenden Fall. Außerdem hätte sich die IDE laut derselben Dokumentation von Anfang an anders verhalten sollen.
Es wird davon ausgegangen, dass Tests in TestComplete mit VBScript geschrieben werden.
Wenn man lange genug hinschaut, kann man das hören. Microsoft schlägt vor, dieses „Wunder“ in PowerShell-Skripte umzuwandeln. Als Alternative können JavaScript und Python verwendet werden, was der Situation hilft.
Als kostenloses Tool wäre TestComplete erträglich, aber ihre Website hat eine Preisseite und die Preise gelten pro Benutzer. Als Ergebnis erhalten wir nach dem Kauf des Tools Folgendes:
- IDE, die Sie schließen möchten
- Kompatibilität mit Skripten von 1996
- Ein Recorder, damit wir nicht alles manuell schreiben
- Noch eine Inspektion, aber mit Schnickschnack
- 2 Arten von Antworten des technischen Supports
- Dokumentation, die nicht die Realität darstellt
Das schlechteste Handelsabkommen aller Zeiten, lass uns weitermachen.
Codierte Benutzeroberfläche
Taktischer Rückzug, Neugruppierung, und wir flankieren das Thema. Einerseits haben wir gelernt, wie man Visual Studio als IDE verwendet. Andererseits basierte unser Ansatz auf den von uns verwendeten DevExpress-UI-Komponenten. Als Ergebnis haben wir einige interessante Informationen über das Coded UI-Framework gefunden, das offiziell in DevExpress verwendet wird, um UI-Tests zu automatisieren. Dieses Framework ist so sehr in den internen Testprozess integriert, dass es sogar eine Visual Studio-Erweiterung dafür gibt.
Es gab eine große Community, Microsoft hat das Tool auf ihrer Website beworben, und dieses Produkt wurde auch auf der „Microsoft Visual Studio“-Kanal. Um es kurz zu machen, alles sah vielversprechend aus und wir begannen mit der Vorbereitung des Frameworks.
Die erste Anforderung, auf die wir stießen, war Visual Studio Enterprise. Darüber hinaus war diese Version von Visual Studio nicht nur für das Schreiben von Tests, sondern auch für deren Ausführung erforderlich. Das bedeutet, dass mstest, durch das der Start im Fall von CI durchgeführt wird, auch Teil der Enterprise-Edition sein sollte.
Alle erforderlichen codierten UI-Tools können installiert werden, indem die entsprechenden Kontrollkästchen aktiviert werden, wenn VS installiert oder geändert wird.
Der Ansatz zum Schreiben von Tests war ziemlich angenehm:In die Shell integrierte Befehle ermöglichten es, schnell einen Rekorder zu starten, der einen Komponententest und eine „map“-Klasse generiert, die die Benutzeroberfläche beschreibt. Zusätzliche in VS integrierte Tools boten die Möglichkeit, separate Testklassen zu erstellen, ohne den Code aufzurufen.
Die einzige Besonderheit, die uns aufgefallen ist, war eine Teilklasse, die die Beschreibung des Steuerelements hatte und in zwei Teile geteilt war. Zusammen mit vielen anderen Dingen ist es in der Dokumentation beschrieben. Diese Dokumentation reicht für einen komfortablen Arbeitsprozess aus:Codebeispiele und Screenshots machen alle technischen Informationen leicht zugänglich und leicht verständlich. Einfach ausgedrückt:Wenn der Rekorder die Benutzeroberfläche beschreibt, wird eine „Designer.cs“-Datei generiert. Diese Datei ist für die Wiederverwendung des Codes verantwortlich, der die Benutzeroberfläche beschreibt. Alles, was der Rekorder nicht verarbeiten konnte, sollte manuell geschrieben und irgendwo außerhalb des automatisch generierten Teils der Klasse gespeichert werden. Dies ist den partiellen Klassen sehr ähnlich, die von VS-Designern beim Erstellen von Steuerelementen geschrieben werden. Die Priorität der Operationen, die an Kontrollen durchgeführt werden, und ihrer Zustandsprüfungen wird in einer Methode beschrieben, der der Recorder hilfreicherweise ein Standard-TestMethod-Attribut hinzufügt.
Die Wolken begannen sich über dem Framework zu verdichten, als wir anfingen, uns mit den Dingen zu befassen, die der Recorder erzeugte . Zunächst wurden einige Probleme der Anwendung verschleiert:Die Name-Eigenschaft einiger Steuerelemente wurde nicht angegeben, und der Rekorder hielt den Aufruf dieses lächerlichen Regelverstoßes für akzeptabel und durchsuchte Steuerelemente im gesamten Text. Außerdem handhabte es komplexe Steuerungen sehr ineffizient. Beispielsweise wurden TreeView-Knoten nach Knotenindex gesucht, was die erstellte Klasse „map“ im Falle einer Schnittstellenerweiterung unbrauchbar machte. Und der Rekorder hat in unseren Augen deutlich an Wert verloren – was nützt es, den Code automatisch zu generieren, wenn man ihn hinterher überprüfen muss?
Wir konnten mit all diesen Dingen Frieden schließen und eine lobenswerte Lösung finden, aber plötzlich schlug der Donner ein:Microsoft erklärt, dass diese Technologie mittlerweile veraltet ist. Damit wurde VS 2019 die letzte Version von Visual Studio, die Coded UI unterstützt. Die Möglichkeit, jetzt und für ein paar Jahre im Voraus von VS 2019 abhängig zu sein, schien nicht wirklich beängstigend zu sein, aber unser Projekt ist ziemlich groß, sodass irgendwann später Schwierigkeiten auftreten könnten (z. B. 2025).
Fassen wir zusammen. Mit Coded UI haben wir:
- Eine leistungsstarke kostenpflichtige IDE
- Sämtliche Infrastruktur bereits für Tests geschaffen:sowohl auf Seiten der IDE als auch unseres CI
- Die Möglichkeit, jeden Entwickler aus unserem Projekt um Hilfe zu bitten, da wir Tests in C# in derselben IDE schreiben
- Eine umfangreiche Dokumentation in guter Qualität
- Ein paar traurige QA-Spezialisten, die ihren Code in den automatisch generierten Teil der Klasse gestellt und ihn dann während des automatischen Generierungsprozesses verloren haben
- Viel generierter Code, der funktioniert und den Sie einer strengen Überprüfung unterziehen müssen
- Ein unglaublich transparenter CI-Ansatz:Sie können mit geschlossenen Augen Code zum Starten von Tests über mstest schreiben
- Ein langsam sterbender roter Riese der Automatisierung, der ständig aus neuen Tests wächst und gefährlich nahe daran ist, sich entweder in einen verblassenden weißen Zwerg zu verwandeln, der durch eine absolut isolierte Maschine mit irreversibel veralteter Software repräsentiert wird, oder in eine Supernova-Explosion, wenn das Projekt unter der Erde implodiert Druck neuer Updates.
Bis auf den letzten Punkt klang alles gut. Aus diesem Grund mussten wir unsere Suche fortsetzen.
TestStack.Weiß
Wir haben mit Hilfe von White an Prototyping-Tests gearbeitet und gleichzeitig die Funktionalität von Coded UI untersucht.
White selbst ist eine Umhüllung der 'Microsoft.Automation'-Bibliotheken, die sehr vielversprechend aussah, und White ist auch Coded ähnlich Benutzeroberfläche. Bei genauerem Hinsehen empfanden wir es jedoch als deutlich nüchterner, und das merkte man überall – vom fehlenden Rekorder bis zum eigentlichen Testaufbau. Wenn Sie beispielsweise die App ausführen, nach einem Fenster suchen und auf die Schaltfläche „Ausführen“ klicken, sieht das so aus:
var appPath = @"C:\Program files\UiAutomatedTestApplication\TestApplication.exe"; var app = TestStack.White.Application.Launch(appPath); var windowSearchCriteria = SearchCriteria.ByAutomationId("MainForm"); var window = app.GetWindow(windowSearchCriteria, InitializeOption.NoCache); var execute = window.GetElement(SearchCriteria.ByText("Execute")); var invokePattern = (InvokePattern)execute.GetCurrentPattern(InvokePattern.Pattern); invokePattern.Invoke(); app.WaitWhileBusy();
Auch wenn es beim Ausführen der Anwendung keine Beanstandungen gibt, ist die Notwendigkeit, mit der InvokePattern-Klasse zu arbeiten, sehr fraglich. Die Klasse InitializeOption sieht auch seltsam aus, weil sie Zugriff auf das statische Member WithCache hat, aber ausschließlich intern verwendet werden soll:
public class InitializeOption { // // Summary: // This option should not be used as this is only for internal white purposes public static InitializeOption WithCache { get; } public static InitializeOption NoCache { get; } public virtual bool Cached { get; } public virtual string Identifier { get; } public virtual bool NoIdentification { get; } // // Summary: // Specify the unique identification for your window. White remembers the location // of UIItems inside a window as you find them. Next time when items inside the // same window is found they are located first based on position which is faster. // // Parameters: // identifier: public virtual InitializeOption AndIdentifiedBy(string identifier); public virtual void NonCached(); public override string ToString(); }überschreiben
Seltsame Entscheidungen wie diese gibt es überall, und das Framework erweist sich als zu abstrakt für QA.
Die Dokumentation ist von ordentlicher Qualität und hat einen guten Gesamteindruck hinterlassen. Der Quellcode des Projekts wurde auf github gehostet, aber der letzte Commit wurde auf den 8. Januar 2016 datiert.
Wenn wir die Informationen über White zusammenfassen, hätten wir:
- Anständige Dokumentation
- Zugriff auf den Quellcode
- Eine kleine Gemeinschaft
- Die Notwendigkeit, allen QA-Spezialisten zu erklären, dass das Verhalten des Steuerelements durch die Musterklasse implementiert wird
- Ein altes Repository, von dem wir definitiv forken müssten
Der unangenehmste Teil war die Notwendigkeit, ein eigenes Framework zu entwickeln, das wir gerne vermeiden würden. Also mussten wir weiter.
Appium
Wir sind bei unserer Suche schon einmal auf Appium gestoßen, haben es aber erst ernsthaft in Betracht gezogen, nachdem Microsoft die Verwendung von Coded UI eingestellt hat.
Auf den ersten Blick sieht das Testen mit Hilfe von Appium aus wie ein Spielautomat mit drei Walzen. Die erste zeigt die Sprache, für die es eine API gibt, die eine Interaktion mit dem Treiber ermöglicht. Dies bietet die Möglichkeit, Tests in jeder vertrauten Sprache zu schreiben:Python, C#, Java usw. Die zweite Rolle zeigt die Treiber-App, die als Zwischenschicht zwischen Tests und dem Produkt dient, das wir testen. Wie in der Dokumentation beschrieben, erfolgt die Interaktion mit Tests über das JSON Wire Protocol – das gibt uns tatsächlich die Möglichkeit, Tests in jeder Sprache zu schreiben. Und die dritte Rolle zeigt das Objekt, das wir testen. Dabei spielt es keine Rolle, ob es sich um eine Website, eine mobile App oder eine Desktop-App handelt, solange der entsprechende Treiber läuft. Wie Sie sehen können, sind die Komponenten elegant austauschbar.
Die Einschätzung der Relevanz des Pakets war zufriedenstellend – auf der Github-Seite konnten wir sehen, dass das Repository frische Commits hatte. Als wir das WinAppDriver-Repository untersuchten, erfuhren wir, dass es sogar einen Rekorder darin gab.
Beim Schreiben eines Prototyps sind uns einige Probleme aufgefallen. Da das Framework beispielsweise zu vielseitig ist, verfügt das für das Desktop-Steuerelement verantwortliche WindowsElement über eine FindElementByCssSelector-Methode, die bei der Ausführung die folgende Ausnahme auslöst:„Unerwarteter Fehler. Nicht implementierter Befehl:CSS-Selektor-Locator-Strategie wird nicht unterstützt“. Im nächsten Artikel werden wir detaillierter auf die Probleme eingehen, auf die wir bei der Arbeit mit diesem Framework gestoßen sind, aber im Moment möchte ich sagen, dass wir es geschafft haben, sie alle zu bewältigen.
Zusammenfassend haben wir Folgendes bei der Verwendung von Appium:
- Die Möglichkeit, Anwendungsfunktionen zu testen, die eine Interaktion mit einem Browser erfordern (Öffnen der Feedback-Seite, Online-Aktivierung, Überprüfen der E-Mail-Zustellung) im Rahmen einer Infrastruktur und eines Tests
- Die Fähigkeit, mit jeder Edition von Visual Studio zu arbeiten
- Die Möglichkeit, eine Desktop-Anwendung zu testen, die einen Browser zum Rendern der Benutzeroberfläche verwendet. Ein gutes Beispiel hierfür wäre Azure Data Studio
- Alle Vorteile, die wir mit Coded UI erhalten
- Ein kostenloses Framework, dessen Verwendung von Microsoft empfohlen wird
- Infrastruktur, die QA-Spezialisten, die mit Selen gearbeitet haben, vertraut ist
- Ein Repository, das mit frischen Commits aktualisiert wurde
- Eine anständig große Community, die jedoch nicht so groß ist wie die Community von Coded UI
- Ein Rekorder mit eingeschränkter Funktionalität
- Die Notwendigkeit, eine Treiberanwendung zum Testen auszuführen. Nicht sehr praktisch, aber es hat seine eigene Protokollierungsfunktion
- Viele Gelegenheiten, sich selbst ins eigene Knie zu schießen aufgrund der unglücklichen Vererbung von WindowsElement von AppiumWebElement
Nachdem wir alle Punkte mit Anforderungen für Frameworks durchgegangen und alle in jedem dieser Frameworks gefundenen Probleme verglichen haben, haben wir uns schließlich für Appium entschieden.
Schlussfolgerung
Es war interessant, mit all diesen Frameworks zu arbeiten, da jedes von ihnen auf einer einzigartigen Philosophie des Herangehens an automatisiertes Testen basierte. Ein Teil von ihnen hat ihren Weg erst begonnen, während andere ihre Sonnenfinsternis erreichten oder bereits verblasst sind. Sie können vermeiden, sich in den vielen verfügbaren Lösungen zu verlieren, indem Sie eine Liste mit spezifischen Anforderungen an das Tool erstellen und ein verantwortliches Team mit einem gut etablierten Zusammenspiel seiner Mitglieder haben. Und vergessen Sie nicht, dass zukünftige Tests genauso ein Projekt sind wie gewöhnlicher Code, mit Backlog, Boards, CI, Refactoring und allem anderen.