iOS-Tests / Spezifikationen TDD / BDD und Integrations- und Abnahmetests

229

Was sind die besten Technologien für die verhaltensgesteuerte Entwicklung auf dem iPhone? Und was sind einige Open Source-Beispielprojekte, die den fundierten Einsatz dieser Technologien demonstrieren? Hier sind einige Optionen, die ich gefunden habe:


Unit Testing

Test :: Unit Style

  1. OCUnit / SenTestingKit, wie im iOS-Entwicklungshandbuch erläutert : Unit-Testing-Anwendungen und andere OCUnit-Referenzen .
  2. FANG
  3. GHUnit
  4. Google Toolbox für Mac: iPhone Unit Testing

RSpec Style

  1. Kiwi (was auch mit Spott und Erwartungen einhergeht)
  2. Zeder
  3. Jasmine mit UI-Automatisierung, wie in den ausführlichen Spezifikationen für iOS-Abnahmetests gezeigt

Abnahmetests

Selen- Stil

  1. UI-Automatisierung (funktioniert auf dem Gerät)

    UPDATE: Zucchini Framework scheint Cucumber & UI Automation zu mischen! :) :)

    Alte Blog-Beiträge:

  2. UISpec mit UISpecRunner

  3. FoneMonkey

Gurke Stil

  1. Frank und iCuke (basierend auf dem Cucumber meets iPhone Talk )

  2. KIF (Keep It Functional) von Square

  3. Zucchini Framework verwendet die Gurkensyntax zum Schreiben von Tests und CoffeeScript für Schrittdefinitionen.

Ergänzungen

Fazit

Natürlich gibt es keine richtige Antwort auf diese Frage, aber ich entscheide mich derzeit für Folgendes:

Für Unit-Tests habe ich OCUnit / SenTestingKit in XCode 4 verwendet. Es ist einfach und solide. Aber ich bevorzuge die Sprache von BDD gegenüber TDD ( Warum ist RSpec besser als Test :: Unit ?), Weil unsere Worte unsere Welt erschaffen. Jetzt verwende ich Kiwi mit ARC & Kiwi-Code-Vervollständigung / Autovervollständigung . Ich bevorzuge Kiwi gegenüber Cedar, weil es auf OCUnit aufgebaut ist und mit Matchers & Mocks / Stubs im RSpec-Stil geliefert wird. UPDATE: Ich beschäftige mich jetzt mit OCMock, da Kiwi derzeit das Stubben von gebührenfreien überbrückten Objekten nicht unterstützt .

Für Abnahmetests verwende ich UI Automation, weil es fantastisch ist. Damit können Sie jeden Testfall aufzeichnen und Tests automatisch schreiben. Apple entwickelt es auch und hat damit eine vielversprechende Zukunft. Es funktioniert auch auf dem Gerät und von Instrumenten, was andere coole Funktionen ermöglicht, wie das Anzeigen von Speicherlecks. Leider weiß ich mit UI Automation nicht, wie man Objective-C-Code ausführt, aber mit Frank & iCuke können Sie das. Also werde ich nur das untergeordnete Objective-C-Zeug mit Komponententests testen oder UIButtons nur für die TESTBuild-Konfiguration erstellen , die beim Klicken Objective-C-Code ausführt.

Welche Lösungen verwenden Sie?

Verwandte Fragen

mattdipasquale
quelle
1
Ich weiß seit mindestens ein paar Monaten, dass in den Schlüssellabors Zeder verwendet wurde. (ähm, ich denke, das ist offensichtlich, da es auf ihrem Github-Konto steht). Mit der Unterstützung eines solchen Geschäfts wäre das meine Wahl.
Jed Schneider
1
Das ist ein guter Punkt. Aber andererseits würde Apple vorschlagen, das Unit-Testing-Framework zu verwenden, nicht Cedar, oder? Also, dann ist es Pivotal Vs. Apfel. Mit was soll ich gehen?
ma11hew28
2
Ich habe einen Beitrag geschrieben, in dem Frank, KIF und UIAutomation verglichen wurden, der für Leser dieses Threads von Interesse sein könnte. Sgleadow.github.com/blog/2011/10/26/…
Stew

Antworten:

53

tl; dr

Bei Pivotal haben wir Cedar geschrieben, weil wir Rspec für unsere Ruby-Projekte verwenden und lieben. Cedar soll OCUnit nicht ersetzen oder mit ihm konkurrieren. Es soll die Möglichkeit des Testens im BDD-Stil für Objective C bieten, genau wie Rspec Pionierarbeit beim Testen im BDD-Stil in Ruby geleistet hat, aber Test :: Unit nicht eliminiert hat. Die Wahl des einen oder anderen hängt weitgehend von den Stilvorlieben ab.

In einigen Fällen haben wir Cedar entwickelt, um einige Mängel bei der Funktionsweise von OCUnit zu beheben. Insbesondere wollten wir den Debugger in Tests verwenden, Tests über die Befehlszeile und in CI-Builds ausführen und nützliche Textausgaben für Testergebnisse erhalten. Diese Dinge können für Sie mehr oder weniger nützlich sein.

Lange Antwort

Die Entscheidung zwischen zwei Test-Frameworks wie Cedar und OCUnit (zum Beispiel) hängt von zwei Dingen ab: dem bevorzugten Stil und der Benutzerfreundlichkeit. Ich werde mit dem Stil beginnen, denn das ist einfach eine Frage der Meinung und der Präferenz. Benutzerfreundlichkeit ist in der Regel eine Reihe von Kompromissen.

Stilüberlegungen gehen über die von Ihnen verwendete Technologie oder Sprache hinaus. xUnit-artige Unit-Tests gibt es schon viel länger als BDD-artige Tests, aber letztere haben schnell an Popularität gewonnen, hauptsächlich aufgrund von Rspec.

Der Hauptvorteil von Tests im xUnit-Stil ist die Einfachheit und breite Akzeptanz (bei Entwicklern, die Komponententests schreiben). Fast jede Sprache, in der Sie Code schreiben könnten, verfügt über ein Framework im xUnit-Stil.

Frameworks im BDD-Stil weisen im Vergleich zum xUnit-Stil in der Regel zwei Hauptunterschiede auf: die Strukturierung des Tests (oder der Spezifikationen) und die Syntax zum Schreiben Ihrer Aussagen. Für mich ist der strukturelle Unterschied das Hauptunterscheidungsmerkmal. xUnit-Tests sind eindimensional mit einer setUp-Methode für alle Tests in einer bestimmten Testklasse. Die Klassen, die wir testen, sind jedoch nicht eindimensional. Wir müssen häufig Aktionen in verschiedenen, möglicherweise widersprüchlichen Kontexten testen. Betrachten Sie beispielsweise eine einfache ShoppingCart-Klasse mit einer addItem: -Methode (für die Zwecke dieser Antwort verwende ich die Objective C-Syntax). Das Verhalten dieser Methode kann sich unterscheiden, wenn der Einkaufswagen leer ist, im Vergleich dazu, wenn der Einkaufswagen andere Artikel enthält. Dies kann abweichen, wenn der Benutzer einen Rabattcode eingegeben hat. es kann abweichen, wenn der angegebene Artikel ' t mit der ausgewählten Versandart versendet werden; usw. Da sich diese möglichen Bedingungen überschneiden, ergibt sich eine geometrisch zunehmende Anzahl möglicher Kontexte. Beim Testen im xUnit-Stil führt dies häufig zu vielen Methoden mit Namen wie testAddItemWhenCartIsEmptyAndNoDiscountCodeAndShippingMethodApplies. Die Struktur von Frameworks im BDD-Stil ermöglicht es Ihnen, diese Bedingungen individuell zu organisieren. Dies erleichtert es mir, sicherzustellen, dass ich alle Fälle abdeckte, und es ist einfacher, einzelne Bedingungen zu finden, zu ändern oder hinzuzufügen. Bei Verwendung der Cedar-Syntax sieht die obige Methode beispielsweise folgendermaßen aus: Beim Testen im xUnit-Stil führt dies häufig zu vielen Methoden mit Namen wie testAddItemWhenCartIsEmptyAndNoDiscountCodeAndShippingMethodApplies. Die Struktur von Frameworks im BDD-Stil ermöglicht es Ihnen, diese Bedingungen individuell zu organisieren. Dies erleichtert es mir, sicherzustellen, dass ich alle Fälle abdeckte, und es ist einfacher, einzelne Bedingungen zu finden, zu ändern oder hinzuzufügen. Bei Verwendung der Cedar-Syntax sieht die obige Methode beispielsweise folgendermaßen aus: Beim Testen im xUnit-Stil führt dies häufig zu vielen Methoden mit Namen wie testAddItemWhenCartIsEmptyAndNoDiscountCodeAndShippingMethodApplies. Die Struktur von Frameworks im BDD-Stil ermöglicht es Ihnen, diese Bedingungen individuell zu organisieren. Dies erleichtert es mir, sicherzustellen, dass ich alle Fälle abdeckte, und es ist einfacher, einzelne Bedingungen zu finden, zu ändern oder hinzuzufügen. Bei Verwendung der Cedar-Syntax sieht die obige Methode beispielsweise folgendermaßen aus:

describe(@"ShoppingCart", ^{
    describe(@"addItem:", ^{
        describe(@"when the cart is empty", ^{
            describe(@"with no discount code", ^{
                describe(@"when the shipping method applies to the item", ^{
                    it(@"should add the item to the cart", ^{
                        ...
                    });

                    it(@"should add the full price of the item to the overall price", ^{
                        ...
                    });
                });

                describe(@"when the shipping method does not apply to the item", ^{
                    ...
                });
            });

            describe(@"with a discount code", ^{
                ...
            });
        });

        describe(@"when the cart contains other items, ^{
            ...
        });
    });
});

In einigen Fällen finden Sie Kontexte, die dieselben Sätze von Zusicherungen enthalten, die Sie mithilfe gemeinsam genutzter Beispielkontexte austrocknen können.

Der zweite Hauptunterschied zwischen Frameworks im BDD-Stil und Frameworks im xUnit-Stil, die Assertions- (oder "Matcher") - Syntax, macht den Stil der Spezifikationen einfach etwas schöner. Manche Leute mögen es wirklich, andere nicht.

Das führt zur Frage der Benutzerfreundlichkeit. In diesem Fall hat jedes Framework seine Vor- und Nachteile:

  • OCUnit gibt es schon viel länger als Cedar und ist direkt in Xcode integriert. Dies bedeutet, dass es einfach ist, ein neues Testziel zu erstellen, und dass es meistens "einfach funktioniert", Tests zum Laufen zu bringen. Auf der anderen Seite stellten wir fest, dass es in einigen Fällen, beispielsweise auf einem iOS-Gerät, nahezu unmöglich war, OCUnit-Tests zum Laufen zu bringen. Das Einrichten von Cedar-Spezifikationen erfordert mehr Arbeit als OCUnit-Tests, da Sie die Bibliothek selbst abgerufen und mit ihr verknüpft haben (in Xcode nie eine triviale Aufgabe). Wir arbeiten daran, die Einrichtung zu vereinfachen, und Vorschläge sind mehr als willkommen.

  • OCUnit führt Tests als Teil des Builds aus. Dies bedeutet, dass Sie keine ausführbare Datei ausführen müssen, damit Ihre Tests ausgeführt werden. Wenn Tests fehlschlagen, schlägt Ihr Build fehl. Dies vereinfacht das Ausführen von Tests in einem Schritt und die Testausgabe wird direkt in Ihr Build-Ausgabefenster verschoben, sodass Sie sie leicht sehen können. Wir haben uns aus mehreren Gründen dafür entschieden, Cedar-Spezifikationen in eine ausführbare Datei zu integrieren, die Sie separat ausführen:

    • Wir wollten den Debugger verwenden können. Sie führen Cedar-Spezifikationen wie jede andere ausführbare Datei aus, sodass Sie den Debugger auf die gleiche Weise verwenden können.
    • Wir wollten eine einfache Anmeldung der Konsole in Tests. Sie können NSLog () in OCUnit-Tests verwenden, aber die Ausgabe wird in das Erstellungsfenster verschoben, in dem Sie den Erstellungsschritt entfalten müssen, um ihn lesen zu können.
    • Wir wollten einfach zu lesende Testberichte, sowohl in der Befehlszeile als auch in Xcode. OCUnit-Ergebnisse werden in Xcode gut im Build-Fenster angezeigt, aber das Erstellen über die Befehlszeile (oder als Teil eines CI-Prozesses) führt zu einer Testausgabe, die mit vielen anderen Build-Ausgaben vermischt ist. Mit getrennten Build- und Run-Phasen trennt Cedar die Ausgabe, sodass die Testausgabe leicht zu finden ist. Der Standard-Cedar-Testläufer kopiert den Standarddruckstil "." für jede übergebene Spezifikation "F" für fehlerhafte Spezifikationen usw. Cedar kann auch benutzerdefinierte Reporterobjekte verwenden, sodass Sie die Ergebnisse mit ein wenig Aufwand nach Belieben ausgeben können.
  • OCUnit ist das offizielle Unit-Testing-Framework für Objective C und wird von Apple unterstützt. Apple verfügt im Grunde über unbegrenzte Ressourcen. Wenn also etwas erledigt werden soll, wird es erledigt. Und schließlich ist dies Apples Sandbox, in der wir spielen. Die Kehrseite dieser Medaille ist jedoch, dass Apple jeden Tag in der Größenordnung von Bajillion Supportanfragen und Fehlerberichten erhält. Sie sind bemerkenswert gut darin, sie alle zu behandeln, aber sie sind möglicherweise nicht in der Lage, Probleme zu behandeln, die Sie sofort oder überhaupt melden. Cedar ist viel neuer und weniger gebacken als OCUnit. Wenn Sie jedoch Fragen, Probleme oder Vorschläge haben, senden Sie eine Nachricht an die Cedar-Mailingliste ([email protected]). Wir werden alles tun, um Ihnen zu helfen. Sie können auch den Code von Github (github.com/pivotal/cedar) abspalten und hinzufügen, was Ihrer Meinung nach fehlt.

  • Das Ausführen von OCUnit-Tests auf iOS-Geräten kann schwierig sein. Ehrlich gesagt habe ich dies seit einiger Zeit nicht mehr versucht, daher ist es vielleicht einfacher geworden, aber als ich es das letzte Mal versuchte, konnte ich einfach keine OCUnit-Tests für eine UIKit-Funktionalität durchführen. Als wir Cedar geschrieben haben, haben wir sichergestellt, dass wir UIKit-abhängigen Code sowohl auf dem Simulator als auch auf Geräten testen können.

Schließlich haben wir Cedar für Unit-Tests geschrieben, was bedeutet, dass es nicht wirklich mit Projekten wie UISpec vergleichbar ist. Es ist schon eine Weile her, dass ich versucht habe, UISpec zu verwenden, aber ich habe verstanden, dass es sich hauptsächlich darauf konzentriert, die Benutzeroberfläche auf einem iOS-Gerät programmgesteuert zu steuern. Wir haben uns ausdrücklich dafür entschieden, Cedar nicht zu veranlassen, diese Art von Spezifikationen zu unterstützen, da Apple (zu diesem Zeitpunkt) UIAutomation ankündigen wollte.

Adam Milligan
quelle
Vielen Dank für die gründliche Antwort. Ich werde das RSpec-Buch lesen und Ceder ausprobieren. Ich habe UISpec in den Selenium-Bereich verschoben und dort auch UIAutomation hinzugefügt. Ich lese Ihren Blog-Beitrag über UIAutomation. Frank sieht tatsächlich viel einfacher und lesbarer aus und ist besser dokumentiert. Ich denke also darüber nach, damit zu beginnen. Ich hoffe nur, dass es so mächtig ist wie UIAutomation. Sie sagen, UIAutomation kann Lebenszyklusprobleme testen. Ich frage mich, ob iCuke auch kann ...
ma11hew28
8

Ich werde Frank in den Akzeptanztest-Mix werfen müssen . Dies ist eine ziemlich neue Ergänzung, hat aber bisher hervorragend für mich funktioniert. Außerdem wird im Gegensatz zu icuke und den anderen tatsächlich aktiv daran gearbeitet.

Raidfive
quelle
5

Für die testgetriebene Entwicklung verwende ich gerne GHUnit , das Einrichten ist ein Kinderspiel und eignet sich auch hervorragend zum Debuggen.

Richard J. Ross III
quelle
Vielen Dank. Ich habe das gesehen, aber vergessen, es zu erwähnen.
ma11hew28
PLus 1 für GHUnit. habe es viel mit OCMock verwendet. Das Einrichten, Erweitern und Arbeiten ist ein Kinderspiel.
Drekka
4

Tolle Liste!

Ich habe eine weitere interessante Lösung zum Testen der Benutzeroberfläche von iOS-Anwendungen gefunden.

Zucchini Framework

Es basiert auf UIAutomation. Mit dem Framework können Sie bildschirmzentrierte Szenarien im Gurkenstil schreiben. Die Szenarien können in Simulator und auf dem Gerät von einer Konsole aus ausgeführt werden (CI-freundlich).

Die Aussagen basieren auf Screenshots. Klingt unflexibel, bietet Ihnen jedoch einen schönen HTML-Bericht mit hervorgehobenem Bildschirmvergleich und Sie können Masken bereitstellen, die die Bereiche definieren, für die eine pixelgenaue Zusicherung erfolgen soll.

Jeder Bildschirm muss beschrieben CoffeScriptund das Tool selbst in Rubin geschrieben sein. Es ist eine Art Polyglott-Albtraum, aber das Tool bietet eine schöne Abstraktion für UIAutomationund wenn die Bildschirme beschrieben werden, ist es sogar für QS-Personen handhabbar.

Benutzer1129998
quelle
Fest! Vielen Dank. Ich habe dies zu der obigen Frage hinzugefügt.
ma11hew28
2

Ich würde iCuke für Abnahmetests und Cedar für Unit-Tests wählen. UIAutomation ist für Apple ein Schritt in die richtige Richtung, aber die Tools benötigen eine bessere Unterstützung für die kontinuierliche Integration. Das automatische Ausführen von UIAutomation-Tests mit Instrumenten ist derzeit beispielsweise nicht möglich.

SamCee
quelle
1

GHUnit eignet sich für Unit-Tests. Für Integrationstests habe ich UISpec mit einigem Erfolg verwendet (Github Fork hier: https://github.com/drync/UISpec ), freue mich aber darauf, iCuke auszuprobieren, da es verspricht, ein leichtes Setup zu sein, und Sie können Verwenden Sie die Schienen, um die Güte zu testen, wie RSpec und Cucumber.

rauben
quelle
1

Ich verwende derzeit Specta für Rspec wie Setups und sein Partner (wie oben erwähnt) Expecta, der jede Menge fantastischer Matching-Optionen bietet.

Keith Smiley
quelle
0

Ich mag OCDSpec2 wirklich, aber ich bin voreingenommen, ich habe OCDSpec geschrieben und zum zweiten beigetragen.

Es ist sogar unter iOS sehr schnell, zum Teil, weil es von Grund auf neu erstellt wurde und nicht auf OCUnit gelegt wird. Es hat auch eine RSpec / Jasmine-Syntax.

https://github.com/ericmeyer/ocdspec2

Eric Smith
quelle