Das Interesse an Flutter hat einen historischen Höchststand erreicht, was sowohl erfreulich als auch dringend nötig ist. Android, iOS, macOS, Web, Windows und Linux werden alle von Googles Open-Source-Software Development Kit (SDK) unterstützt. All diese werden von einer einzigen Codebasis für Flutter unterstützt. Und Unit-Tests sind unerlässlich, um ein Flutter-Programm bereitzustellen, das zuverlässig und konsistent ist. Diese Tests schützen die App vor Fehlern, Störungen und anderen Arten von Mängeln, indem sie die Codequalität vor der Zusammenstellung proaktiv verbessern.
Was ist automatisiertes Testen?
Der Prozess der Überprüfung und Verifizierung, ob eine Softwareanwendung das tut, was sie tun soll, wird als automatisiertes Softwaretesten bezeichnet. Es beseitigt Fehler und senkt die Gesamtkosten der Entwicklung.
Um das zu verstehen, muss man etwas verstehen. Der einzige Zweck des automatisierten Testens besteht darin, die Software vor bereits vorherbestimmten Fehlern zu schützen. Das bedeutet nicht, dass die Software völlig fehler- oder bugfrei ist. Es bedeutet lediglich, dass die Software keine typischen Fehler enthält.
Nach der Entwicklungsphase schreiben wir die erwarteten Testfälle (TDD ist eine Ausnahme). In den meisten Fällen liefern wir die Software aus, sobald sie alle Testfälle erfolgreich bestanden hat. Nehmen wir jedoch an, dass ein Fehler entdeckt wird, während die Software in der Produktion verwendet wird. In diesem Fall werden wir ihn beheben und dann die Testfälle schreiben, um zu verhindern, dass die Software in Zukunft denselben Fehler enthält.
Testen ist nichts anderes als der Akt des Verifizierens von etwas. Bei der Entwicklung einer neuen Funktion oder der Behebung eines vorhandenen Fehlers helfen uns Testfälle dabei, festzustellen, ob alle zuvor implementierten Funktionen und Einheiten wie vorgesehen funktionieren. Dadurch wird sichergestellt, dass die laufende Entwicklung keine der bereits vorhandenen Funktionen beeinträchtigt.
„Tests zeigen, dass es Fehler gibt, nicht, dass es keine gibt.“ – Edsger Dijkstra
Unit-Tests werden in Flutter auf eine Weise implementiert, die der Implementierung in anderen Technologie-Stacks sehr ähnlich ist. In Flutter folgen Sie den folgenden Prozessen:
- Analysieren Sie den Code.
- Richten Sie ein Daten-Mocking ein.
- Definieren Sie den Test für die Gruppe(n).
- Definieren Sie die Testfunktionssignatur (oder Signaturen) für jede Testgruppe.
- Schreiben Sie die Tests.
Was ist Unit-Testing?
Der automatisierte Testprozess umfasst einen Schritt namens „Unit-Test“, bei dem die Zuverlässigkeit kleinerer Codeblöcke überprüft wird, indem sie in verschiedenen Anwendungsfällen ausgeführt werden. Eine Unit kann alles sein, von einer Variable über eine Funktion bis hin zu einer Methode, einer Klasse bis hin zu einem Zustand.
Die erste und grundlegendste Testebene wird als Unit-Test bezeichnet. Auf dieser Ebene testen wir die Funktionalität der zugrunde liegenden Komponenten jeder Funktion.
Ein Unit-Test besteht aus drei Phasen:
- Anordnen
- Handeln
- Bestätigen
Während der Anordnungsphase muss das Objekt der zu testenden Unit festgelegt und die Voraussetzungen für unseren Test vorbereitet werden. Zu diesen Vorbereitungen gehören unter anderem das Einrichten der Zustandsvariable und von Mocks. Je nach Anforderungen ist die Anordnungsphase natürlich möglicherweise überhaupt nicht erforderlich.
Während der Handlungsphase testen wir die Unit auf Herz und Nieren, indem wir Argumente übergeben und einige Zustände ändern, bevor wir das Ergebnis speichern, falls es eines gibt.
Während des Bestätigen-Schritts überprüfen wir, ob sich die Unit wie erwartet verhält. Wir können beispielsweise davon ausgehen, dass eine bestimmte Methode aufgerufen wird oder dass das Ergebnis dem erwarteten entspricht.
Ist Unit-Testing wichtig?
Das Schreiben und Ausführen von Unit-Tests ist ein einfacher Vorgang. Dies führt zu erheblichen Zeiteinsparungen.
Durch Unit-Tests können wir Fehler in einem früheren Stadium aufdecken. Dies führt zu erheblichen Kosten- und Zeiteinsparungen.
Da wir über alle möglichen Ergebnisse der Einheit schreiben, ist es für jeden leicht zu verstehen, worum es bei der Einheit geht. Dies führt zu einer verbesserten Dokumentation.
Da die Einheit dadurch möglicherweise unbrauchbar wird, überarbeiten wir Ihren Code nicht zu oft. Stattdessen gibt uns die Anwesenheit von Unit-Tests die notwendige Sicherheit, unseren Code zu überarbeiten.
Das Debuggen ist unkompliziert. Da wir über vollständige Kenntnis der Fehlersituationen verfügen, können wir uns auf die spezifische Einheit konzentrieren, die die Ursache des Fehlers ist.
Ein einfacher Blick auf die Testfälle gibt uns ein klares Bild davon, was die Einheit verstehen soll. Dies vereinfacht die Wartung auf lange Sicht.
Was können wir mit Unit-Tests testen?
Um einen zuverlässigen Satz von Unit-Tests zu erstellen, müssen wir zunächst die Elemente verstehen, die in jeder einzelnen Unit validiert werden müssen.
Unit-Tests konzentrieren sich häufig auf die folgenden Elemente:
- Zustandsvariablen
- Funktions-/Variablenaufrufe
- Die Argumente der Funktion
- Funktionsrückgaben
Variablen, die zum Zustand gehören, sind Variablen, die außerhalb des lokalen Gültigkeitsbereichs existieren. Dies kann eine Klasseneigenschaft oder eine globale Variable sein, auf die mehr als eine Unit zugreifen kann. In den meisten Fällen behält sie einen Zustand bei.
In einer Unit behalten wir unter anderem die folgenden Szenarien im Auge:
- Überprüfen, ob der Wert der Konstanten oder der endgültigen Variable korrekt ist.
- Werte am Anfang der Zustandsvariablen.
- Überprüfen, ob eine bestimmte Funktion 1…n-mal von der Unit aufgerufen wird.
- Überprüfen, ob die Unit niemals eine bestimmte Funktion aufruft.
- Überprüfen, ob die Zustandsvariablen wie erwartet aktualisiert werden.
- Das Ergebnis der Unit war genau das gleiche wie erwartet.
- Achten Sie darauf, auf leere Situationen zu achten, wenn eine Zeichenfolge, Liste oder ein anderer Typ eines komplizierten DS beteiligt ist; dies ist besonders wichtig, wenn wir den DS durchlaufen.
- Prüfen Sie auf Fälle von Null (nur für Typen, die Null sein können). Dart ist jetzt sicher gegen Null)
- Prüfen Sie den Typ der Variablen oder des Arguments (obwohl dies möglicherweise nicht erforderlich ist, wenn wir das Typsystem von Dart effektiv verwenden).
Einige Punkte zum Betrieb von Flutter: Wenn ein Projekt erstellt wird, wird der Testprozess durch das Framework dank des automatischen Ladens der Flutter-Testbibliothek vereinfacht. Flutter kann jetzt dank der Beiträge der Bibliothek Unit-Tests lesen, ausführen und auswerten. Darüber hinaus wird der Testordner, in dem Tests gespeichert werden, auch automatisch von Flutter erstellt. Daher ist es äußerst wichtig, den Testordner nicht umzubenennen oder zu verschieben, da dies seine Funktionalität und infolgedessen unsere Fähigkeit zur Ausführung von Tests beeinträchtigt. Darüber hinaus ist es wichtig, den Namen unserer Testdateien das Suffix _test.dart hinzuzufügen. Dies liegt daran, dass Flutter dieses Suffix verwendet, um Testdateien zu identifizieren.
Wir werden einen geordneten Speicherbereich für die Testdateien einrichten, die wir schreiben werden, ein System, in dem verschiedene Testgruppen jeweils ihre eigenen „Heime“ haben, die sofort erkannt werden. Angesichts der von Flutter auferlegten Notwendigkeit, Tests im Testordner zu lokalisieren, replizieren wir die Ordnerstruktur unseres Quellcodes und stellen sie unter Test. Danach werden wir jedes Mal, wenn wir einen neuen Test schreiben, ihn in den entsprechenden Unterordner legen, die wie folgt lauten: Unit-Tests von Modellklassen sollten in einem Ordner mit dem Titel „Modell“ abgelegt werden, ähnlich wie saubere Socken in die Sockenschublade Ihrer Kommode und gefaltete Hemden in die Hemdschublade gelegt werden sollten.
Die Übernahme dieses Dateiformats bringt Offenheit in das Projekt. Es bietet der Gruppe eine unkomplizierte Methode, um festzustellen, welche Teile unseres Codes entsprechende Tests haben.
Was sind einige der Best Practices für Unit-Tests?
- Die Unit-Tests müssen schnell sein.
- Unit-Tests sollten unkompliziert sein. Unit-Tests sollten vorbestimmt sein.
- Der Schwerpunkt sollte auf Unit-Tests liegen.
- Bei Unit-Tests ist es zulässig, Code zu wiederholen.
- Die Beschreibung des Tests muss unkompliziert sein.
- Unit-Tests müssen schnell sein. Da wir die gesamte Testsuite während der gesamten Entwicklungsphase selbst ausführen, sollte jeder Unit-Test in unserer Testsuite in weniger als einer Minute ausgeführt werden können. Dies hilft bei der frühzeitigen Erkennung und Korrektur von Fehlern. Wenn es länger dauert, integrieren wir diesen Job normalerweise in eine Pipeline irgendeiner Art.
Unit-Tests sollten unkompliziert sein. Wenn wir einen Unit-Testfall durchgehen, sollten alle erforderlichen Informationen in diesem Testfall enthalten sein. Es ist nicht zulässig, dass wir durch den Code navigieren, um einen einzelnen Testfall zu verstehen. Daher sollte der Unit-Test keine Erklärung erfordern.
Auf Unit-Tests sollte Determinismus angewendet werden. Ohne Änderungen am Quellcode sollte ein Unit-Test immer genau dasselbe Verhalten reproduzieren, unabhängig davon, wo oder wann er getestet wird. Die Ergebnisse eines Unit-Tests sollten nicht von externen Variablen oder Bedingungen abhängen, wie etwa der aktuellen Uhrzeit, einer Datenbank, dem Web oder einer nativen API. In den meisten Fällen machen wir uns darüber lustig.
Der Fokus sollte auf den Unit-Tests liegen. Eine einzelne Unit sollte der einzige Fokus eines Unit-Tests sein. Im Kontext eines Unit-Tests sollten wir die Abhängigkeiten nicht testen.
Bei Unit-Tests ist es zulässig, Code zu wiederholen. Das Ziel eines Unit-Tests sollte es sein, sicherzustellen, dass der getestete Code so unkompliziert wie möglich ist. Es sollte für jeden möglich sein, den Testfall zu verstehen, ohne seine Abhängigkeiten oder den aktuellen Zustand der Unit untersuchen zu müssen. Daher ist es in Ordnung, bestimmte Codeteile zu wiederholen, wenn dies das Programm leichter verständlich und unkomplizierter macht.
Die Beschreibung des Unit-Tests sollte unkompliziert sein. Eine gute Beschreibung muss aus vier Teilen bestehen:
- Die Unit, die getestet wird
- Der Zustand, in dem sich die Unit im Moment befindet
- Der Beitrag, den wir leisten werden
- Die Reaktion, auf die wir uns vorbereiten.
Verspottung
Das Hauptziel von Unit-Tests besteht darin, die gerade bewertete Einheit zu unterteilen und auf Null zu reduzieren, anstatt sich auf das Testen eventuell vorhandener anderer Abhängigkeiten zu konzentrieren. In den meisten Fällen müssen wir uns jedoch auf andere Abhängigkeiten wie Datenbankserver, Webserver, Plattform-APIs und andere externe Geräte und Komponenten verlassen.
Nehmen wir für den Moment an, dass unsere vorhandene Einheit von einer Web-API abhängig ist. Der Test wird langsam, aber erfolgreich abgeschlossen, wenn er auf einem Live-Server ausgeführt wird. Der Unit-Test schlägt jedoch fehl, wenn der Server nicht verfügbar ist. Dies führt zu Unvorhersehbarkeit im Unit-Test. Denn wir haben dann keine Kontrolle mehr über den Webserver. Wenn der Webserver ausfällt, ist das nicht unsere Schuld. An dieser Stelle kommt Mocking zum Einsatz.
Im Kontext von Unit-Tests bezieht sich „Mocking“ auf den Prozess, der ausgeführt wird, wenn die getestete Einheit von externen Ressourcen abhängig ist. Mocking wird verwendet, um den getesteten Code zu isolieren und sich darauf zu konzentrieren, anstatt auf das Verhalten externer Abhängigkeiten.
MockTail ist eine Abkürzung für „Without Code Generation“.
Das Hauptziel von Mocktails ist es, eine unkomplizierte und bekannte API für die Entwicklung von Mocks in Dart bereitzustellen, komplett mit Nullsicherheit, ohne dass eine manuelle Mock-Erstellung oder Codegenerierung erforderlich ist.
Felix Angelov, dieselbe Person, die Bloc, Equatable und andere ähnliche Programme erstellt hat, ist der Autor dieser Bibliothek. Noch beeindruckender als seine anderen Pakete ist die Tatsache, dass diese Bibliothek ihren Code vollständig abdeckt.
Wenden Sie sich jetzt an uns, um die besten Unit-Testing-Dienste zu erhalten und sich von Unit-Testing-Experten beraten zu lassen!
FAQs
Was sind Unit-Tests in Flutter?
Unit-Tests sind sehr hilfreich, wenn die Funktionsweise einer einzelnen Methode, Klasse oder Funktion überprüft wird. Das Testpaket bietet die grundlegende Infrastruktur für die Entwicklung von Unit-Tests und das Flutter-Testpaket enthält zusätzliche Dienstprogramme zum Testen von Widgets.
Wie viele Arten von Unit-Tests unterstützt das Flutter-Framework?
Mit Flutter können drei verschiedene Arten von Tests ausgeführt werden. Zunächst wird die Funktionsweise einer Methode oder Klasse durch einen Unit-Test validiert. Ohne die App selbst tatsächlich auszuführen, kann die Funktionalität von Flutter-Widgets mithilfe eines Widget-Tests validiert werden. Schließlich wird die gesamte Anwendung einem sogenannten Integrationstest unterzogen, der auch als End-to-End-Test oder GUI-Test bezeichnet wird.
Was ist in Flutter erforderlich, um einen Unit-Test zu erstellen?
Der Prozess zum Durchführen von Unit-Tests in Flutter ist identisch mit dem Verfahren, das in den meisten anderen Frameworks verwendet wird. Nachdem die zu testenden Klassen und Funktionen (die Testfälle) festgelegt wurden, besteht der nächste Schritt darin, den Code auszuwerten, Datensimulationen einzurichten, die Testgruppen zu definieren, die Testfunktionssignaturen für jede Testgruppe zu definieren, die Tests zu schreiben und sie auszuführen.
Warum ist es wichtig, Unit-Tests durchzuführen?
Unit-Tests können die Anzahl der Fehler in einer Anwendung beseitigen oder deutlich reduzieren, was zu einer verbesserten Benutzererfahrung führt, sobald eine App der Öffentlichkeit zugänglich gemacht wird. Darüber hinaus ist das Lesen von Unit-Tests eine großartige Möglichkeit, neuen Entwicklern beim Lernen und Verstehen Ihres Codes zu helfen, was ein zusätzlicher Vorteil ist.