Unit Tests vs. Mocks in iOS-Apps

SVG-Kredit geht an Raz Cohen (danke für die Pfeifen)

Sie haben gerade ein Projekt gestartet. Gemäß der typischen Mode werden verschiedene Personen zu verschiedenen Zeitpunkten hereingebracht. In der Anfangsphase sind es nur Sie und der Designer. Im Verlauf des Projekts wird jedoch ein Web-API-Entwickler hinzugezogen, um einen Web-Service zu erstellen, den Sie schließlich mit der Benutzeroberfläche Ihrer App verbinden können.

Dies schafft ein Rätsel, das viele Entwickler mit sehr unterschiedlichem Erfolg angehen. Wie können Sie die App und ihre Benutzeroberfläche erstellen, ohne auf den Webdienst angewiesen zu sein?

Ist so etwas überhaupt möglich oder empfehlenswert? Ist das, was Unit-Tests sind?

Die Leute, die mit einer Sache namens Test Driven Development hausieren, würden ja sagen. Sie würden argumentieren, dass Sie zuerst die Tests schreiben und dann Produktionscode schreiben möchten, der die Tests besteht.

Das ist alles gut und schön in Märchenland, wo die Leute anscheinend die Zeit dazu haben, aber die meisten von uns haben ungefähr ein oder zwei Monate Zeit, um eine Art lösbares Ding für unsere Kunden zu bauen.

Die Idee, die Komponententests zu schreiben, um alle Funktionen (einschließlich des Aussehens der Benutzeroberfläche) zu validieren, bevor alle an Bord gebracht werden, ist einfach unrealistisch.

Schreiben Sie keine Tests, bei denen Verspottungen ausreichen

Mocks sind das richtige Werkzeug für den Job. Ein Mock ist eine gefälschte Entität, ein Modell oder eine Dienstleistung. Eine App in einem frühen Stadium sollte alle Arten von Verspottungen haben. Sie können gefälschte Benutzer, gefälschte Ereignisse, gefälschte Orte und gefälschte Netzwerkdienste haben. Alles sollte falsch sein.

Aber während Ihre Modelle und Dienste gefälscht sind, können Ihre Ansichten, Ansichtssteuerungen und andere Anwendungslogik tatsächlich sehr real sein. Das ist der springende Punkt, etwas zu verspotten.

Ihre App ist wie eine Form. Stellen Sie zuerst gefälschte Sachen ein und später die echten Sachen

Es ist, als würde man eine Brotform herausdrücken. Sie können ein Stück Holz verwenden, um die richtige Form zu erhalten, aber Sie möchten beim Backen unbedingt echten Teig hineinlegen.

Sie können ein App-Projekt mit gefälschten Modellen und Diensten starten, diese zwischen verschiedenen ViewControllern austauschen und den größten Teil der Benutzerinteraktion Ihrer App ausbauen. Später, wenn der Webentwickler in das Team aufgenommen wurde, können Sie langsam damit beginnen, Ihre gefälschten Modelle und Services durch das echte Angebot zu ersetzen.

Wenn Sie Entwurfsmuster wie Model View Controller und Model View View-Model verwendet haben, sollte das Austauschen Ihrer Mocks mit realen Entitäten eine triviale Aufgabe sein. Meistens ist es einfach, einen Klassennamen zu ändern oder einen Initialisierer hinzuzufügen, der einen JSON-Code benötigt.

Wie sieht ein Mock aus?

Ein guter Mock ist so nah wie möglich an der Realität. Wenn Ihre App also eine Benutzerentität mit einem Vornamen, Nachnamen, einer E-Mail-Adresse und einem Profilbild hat, sollte Ihr Scheinbenutzer dieselben Eigenschaften haben.

Tatsächlich sind Ihre nachgebildeten Modelle möglicherweise vollständig mit Ihren endgültigen Modellen identisch. Das ist es, wonach Sie streben. Sie möchten etwas, das bereit ist, mit echten Daten zu füllen, sobald diese verfügbar sind.

Ich habe gesehen, wie in verschiedenen iOS-Teams auf vielfältige Weise verspottet wurde.

Die weniger fortgeschrittenen Teams verinnerlichen niemals die Konzepte von Model-View-Controller, MVVM oder Trennung von Interessen. Sie erstellen lose geordnete Arrays unterschiedlicher Daten und erwarten, dass sie später wieder zurückkehren und ihre gesamte Arbeit wiederholen.

Infolgedessen sehen ihre Verspottungen normalerweise so aus

Sie sehen, wie wenig über die Architektur der App nachgedacht wird. Sie speichern lediglich einige Daten in den Arrays und gehen davon aus, dass sie die App erst dann entwickeln können, wenn der Webdienst verfügbar ist.

Aber das stimmt einfach nicht! Sie können eine Struktur erstellen, obwohl Ihre Daten nicht echt sind.

So erstellen Sie eine Architektur, wenn die Daten gefälscht sind

Die fortgeschritteneren Teams werden ihre Mocks so behandeln, als wären sie die echten Modelle, die sie langfristig einsetzen wollen. Sie werden sie zwischen ViewControllern weitergeben, so wie sie den eigentlichen Deal weitergeben würden.

Infolgedessen sehen die Mocks eines großartigen Teams ungefähr so ​​aus

Es ist fraglich, ob Sie das Protokoll benötigen oder nicht. Ich habe es hier eingefügt, um die Idee hervorzuheben, dass eine Person eine Abstraktion ist, die sowohl für falsche als auch für echte Personen gilt. Um Fake mit Real zu tauschen, müssen Sie nur eine neue Entität erstellen, die dem Personenprotokoll entspricht.

Der Unterschied ist auffällig und klar. Das erfahrenere Team hat eine bewährte Architektur geschaffen. Das weniger erfahrene Team erstellte eine Sammlung von Dingen, die nichts miteinander zu tun hatten.

Das Senior-Team kann die App mit Mocks umgehen, als wären sie das Original. Sie können 90% der Arbeit erledigen, ohne jemals etwas mit dem eigentlichen Webservice zu tun haben zu müssen.

In der Zwischenzeit wird das Junior-Team Schwierigkeiten haben, Funktionen zu erstellen, bevor der Webdienst verfügbar wird. Ihr Code ist nicht sauber in Entitäten (a.k.a. Modelle) organisiert, die an andere Ansichtscontroller übergeben werden können. Selbst wenn ihre App Daten zwischen Controllern überträgt, wird dies schlampig und willkürlich geschehen.

Es spielt keine Rolle, ob die Daten in den Modellen falsch sind. Was zählt, ist die Organisation dieser Daten.

Mocks sind, obwohl gefälscht, immer noch eine Art Klempnerarbeit. Wenn Sie sie in Ihrer gesamten App verwenden, gilt dies immer noch als Erweiterung der Architektur. Sobald die realen Daten verfügbar sind, müssen Sie nur noch ein paar winzige Änderungen am Code vornehmen, damit die realen Daten fließen können.

Warum spielt irgendetwas davon eine Rolle?

Warum spreche ich über die unterschiedlichen richtigen und falschen Methoden zum Verspotten einer Benutzeroberfläche in Ihrer App?

Heutzutage scheint es einige Verwirrung hinsichtlich der richtigen Verwendung für automatisierte Komponententests zu geben. Einige Leute scheinen zu denken, Unit-Tests sollten als Ersatz für Mocks in den frühen Phasen der App-Entwicklung verwendet werden.

Die Wahrheit ist, dass viele der Vorteile, die Menschen ansonsten Unit-Tests zuschreiben würden, auf anderen Best Practices beruhen, die Unit-Tests fördern.

Ich spreche von Dingen wie der Trennung von Bedenken, der Verwendung von gängigen Entwurfsmustern wie MVC oder MVVM und dem allgemeinen Versuch, eine Codeduplizierung zu vermeiden.

Während es nie schlecht ist, einige Unit-Tests in der Anfangsphase durchzuführen, ist eine saubere, modulare Organisation der wahre Grund, warum das Senior-Team die App zu 90% abgeschlossen haben kann, bevor der Webdienst verfügbar ist.

In ähnlicher Hinsicht hat das Juniorenteam keine Probleme, da es nicht weiß, wie man Komponententests schreibt. Sie kämpfen, weil sie das Konzept der Trennung von Anliegen nicht verinnerlicht haben.

Angesichts der Tatsache, dass sich rund 80% der iOS-App-Entwicklung mit Benutzeroberflächen befasst, ist die Vorstellung, dass Komponententests Mocks ersetzen, auf den ersten Blick falsch. Wir sollten frühzeitig mehr visuelle Tests durchführen, nicht weniger.

Mocks erfordern viel weniger Setup als Unit-Tests und sind in vielen Fällen eine sehr enge Annäherung an die endgültigen Modelle, die verwendet werden, sobald die tatsächlichen Daten und Dienste verfügbar sind.

Wenn Sie einfach nur eine bestimmte Navigation durcharbeiten möchten oder sehen möchten, wie ein Bildschirm aufgebaut wird, verwenden Sie Mocks anstelle von Komponententests. Auf diese Weise arbeiten Sie viel schneller und können visuell bestätigen, dass alles gut aussieht .

Unterstütze meinen Kickstarter bei Unit Tests für iOS Apps

Ob Sie es glauben oder nicht, ich mache gerade einen Kickstarter für einen Udemy-Kurs zu Komponententests für iOS-Apps.

Unit-Tests für Swift 4 und iOS 11

Kein Gemüse. Nur praktische Tipps.

Ich möchte Unit-Tests anhand von Beispielen aus der Praxis praktischer darstellen, bei denen das Schreiben von Unit-Tests tatsächlich Zeit spart.

Ich möchte den Leuten beibringen, wie man Logik effizient testet, die sich nur schwer manuell testen lässt. Ich spreche von Bedingungen, deren Auslösung selten oder zeitaufwendig ist.

Ich möchte diesen Paternalismus „iss dein Gemüse“ abschaffen und dir einige Techniken zeigen, die dich produktiver machen.

Wenn Ihnen das, was Sie hier lesen, gefällt, zeigen Sie bitte Ihre Unterstützung und unterstützen Sie das Projekt für nur 1 USD

Auch wenn Sie es sich nicht leisten können, teilen Sie den Link in den sozialen Medien. Das ist eine große Hilfe. Danke für deine Unterstützung!