web-dev-qa-db-fra.com

Tests iOS / Spécifications TDD / BDD et tests d'intégration et d'acceptation

Quelles sont les meilleures technologies à utiliser pour le développement basé sur le comportement sur iPhone? Et quels sont quelques exemples de projets open source démontrant une utilisation judicieuse de ces technologies? Voici quelques options que j'ai trouvées:


Test Unitaire

Test :: Unité Style

  1. OCUnit/SenTestingKit comme expliqué dans Guide de développement iOS: Applications de test unitaire & autres références OCUnit .
  2. ATTRAPER
  3. GHUnit
  4. Google Toolbox pour Mac: Test unitaire iPhone

RSpec Style

  1. Kiwi (qui vient aussi avec des moqueries et des attentes)
  2. Cèdre
  3. Jasmine avec I Automation comme indiqué dans spécifications dexterous iOS-Acceptance-Testing

Test d'acceptation

Sélénium Style

  1. UI Automation (fonctionne sur le périphérique)

    UPDATE: Zucchini Framework semble mélanger le concombre et l'automatisation de l'interface utilisateur! :)

    Anciens messages de blog:

  2. ISpec avec ISpecRunner

  3. FoneMonkey

Concombre Style

  1. Frank et iCuke (basé sur le le concombre rencontre la conversation iPhone )

  2. KIF (Keep It Functional) par carré

  3. Zucchini Framework utilise la syntaxe Cucumber pour écrire des tests et utilise CoffeeScript pour les définitions d'étape.

Ajouts

Conclusion

Bien évidemment, il n’ya pas de bonne réponse à cette question, mais voici ce que je choisis d’utiliser pour le moment:

Pour les tests unitaires, j'avais l'habitude d'utiliser OCUnit/SenTestingKit en XCode 4. C'est simple et solide. Mais, je préfère le langage de BDD à TDD ( Pourquoi RSpec est-il meilleur que Test :: Unit ?) Parce que nos mots créent notre monde. Alors maintenant, j'utilise Kiwi avec ARC & Achèvement du code Kiwi/autocomplétion . Je préfère le Kiwi au Cedar car il est construit sur OCUnit et est fourni avec des adaptateurs et des mock/stubs de style RSpec. UPDATE: J'examine maintenant OCMock car, actuellement, le kiwi ne prend pas en charge le stubbing des objets pontés sans frais .

Pour les tests d'acceptation, j'utilise UI Automation parce que c'est génial. Il vous permet d’enregistrer chaque cas de test, ce qui rend l’écriture automatique des tests. En outre, Apple le développe, ce qui en fait un avenir prometteur. Il fonctionne également sur le périphérique et à partir d'Instruments, ce qui permet d'autres fonctionnalités intéressantes, telles que l'affichage des fuites de mémoire. Malheureusement, avec UI Automation , Je ne sais pas comment utiliser le code Objective-C, mais avec Frank & iCuke, vous le pouvez. Je vais donc simplement tester les éléments Objective-C de niveau inférieur avec des tests unitaires ou créer UIButtons uniquement. pour le TEST configuration de construction , qui, une fois cliqué dessus, exécutera le code Objective-C.

Quelles solutions utilisez-vous?

Questions connexes

229
ma11hew28

tl; dr

Chez Pivotal, nous avons écrit Cedar parce que nous utilisons et adorons Rspec dans nos projets Ruby. Cedar ne vise pas à remplacer ou à faire concurrence à OCUnit; C, tout comme Rspec a été le pionnier des tests de style BDD dans Ruby, mais n’a pas encore éliminé Test :: Unit.

Dans certains cas, nous avons conçu Cedar pour remédier à certaines lacunes dans la manière dont OCUnit fonctionne pour nous. Plus précisément, nous voulions pouvoir utiliser le débogueur dans les tests, exécuter des tests à partir de la ligne de commande et dans des versions de CI, et obtenir une sortie texte utile des résultats de test. Ces choses peuvent vous être plus ou moins utiles.

Longue réponse

Décider entre deux frameworks de test comme Cedar et OCUnit (par exemple) revient à deux choses: le style préféré et la facilité d'utilisation. Je vais commencer par le style, parce que c'est simplement une question d'opinion et de préférence; la facilité d'utilisation a tendance à être un ensemble de compromis.

Les considérations de style transcendent la technologie ou le langage que vous utilisez. Les tests unitaires de type xUnit existent depuis beaucoup plus longtemps que les tests de style BDD, mais leur popularité a rapidement gagné en popularité, principalement grâce à Rspec.

Le principal avantage des tests de type xUnit est leur simplicité et leur large adoption (parmi les développeurs qui écrivent des tests unitaires); Presque toutes les langues dans lesquelles vous pourriez envisager d'écrire du code disposent d'un framework de type xUnit.

Les frameworks de style BDD ont généralement deux différences principales par rapport au style xUnit: la structure du test (ou des spécifications) et la syntaxe utilisée pour écrire vos assertions. Pour moi, la différence structurelle est le différentiateur principal. Les tests xUnit sont unidimensionnels, avec une méthode setUp pour tous les tests d'une classe de tests donnée. Les classes que nous testons, cependant, ne sont pas unidimensionnelles; nous avons souvent besoin de tester des actions dans plusieurs contextes différents, potentiellement conflictuels. Par exemple, considérons une classe ShoppingCart simple, avec une méthode addItem: (pour les besoins de cette réponse, j'utiliserai la syntaxe Objective C). Le comportement de cette méthode peut différer lorsque le panier est vide par rapport à celui où il contient d'autres éléments. cela peut différer si l'utilisateur a entré un code de réduction; il peut être différent si l'article spécifié ne peut pas être expédié par la méthode d'expédition sélectionnée; etc. Lorsque ces conditions possibles se croisent, vous obtenez un nombre croissant de contextes possibles. dans les tests de type xUnit, cela conduit souvent à de nombreuses méthodes portant des noms tels que testAddItemWhenCartIsEmptyAndNoDiscountCodeAndShippingMethodApplies. La structure des frameworks de style BDD vous permet d’organiser ces conditions individuellement, ce qui, selon moi, facilite la couverture de tous les cas, ainsi que la recherche, la modification ou l’ajout de conditions individuelles. Par exemple, en utilisant la syntaxe Cedar, la méthode ci-dessus ressemblerait à ceci:

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, ^{
            ...
        });
    });
});

Dans certains cas, vous trouverez des contextes contenant les mêmes ensembles d'assertions que vous pouvez DRY en utilisant des exemples de contextes partagés.

La deuxième différence principale entre les frameworks de style BDD et les frameworks de style xUnit, la syntaxe d'assertion (ou "matcher"), rend simplement le style des spécifications un peu plus agréable; certaines personnes l'aiment vraiment, d'autres pas.

Cela pose la question de la facilité d'utilisation. Dans ce cas, chaque cadre a ses avantages et ses inconvénients:

  • OCUnit existe depuis beaucoup plus longtemps que Cedar et est directement intégré à Xcode. Cela signifie qu'il est simple de créer une nouvelle cible de test et, le plus souvent, de lancer des tests et de les exécuter "ne fonctionne que". D'autre part, nous avons constaté que dans certains cas, tels que l'exécution sur un périphérique iOS, il était pratiquement impossible de faire fonctionner les tests OCUnit. La configuration des spécifications de Cedar demande plus de travail que les tests OCUnit, car vous avez la bibliothèque et la liaison vous-même (jamais une tâche triviale dans Xcode). Nous travaillons à faciliter la configuration et toutes les suggestions sont les bienvenues.

  • OCUnit exécute des tests dans le cadre de la construction. Cela signifie que vous n'avez pas besoin d'exécuter un exécutable pour exécuter vos tests; si des tests échouent, votre construction échoue. Cela simplifie le processus d’exécution des tests et permet d’afficher directement la sortie de test dans la fenêtre de sortie de votre construction. Nous avons choisi d'intégrer les spécifications de Cedar dans un exécutable que vous exécutez séparément pour plusieurs raisons:

    • Nous voulions pouvoir utiliser le débogueur. Vous exécutez les spécifications de Cedar comme n'importe quel autre exécutable, vous pouvez donc utiliser le débogueur de la même manière.
    • Nous voulions une connexion facile à la console lors des tests. Vous pouvez utiliser NSLog () dans les tests OCUnit, mais la sortie passe dans la fenêtre de construction où vous devez déplier l’étape de construction pour la lire.
    • Nous voulions des rapports de test faciles à lire, à la fois en ligne de commande et dans Xcode. Les résultats d'OCUnit apparaissent bien dans la fenêtre de construction de Xcode, mais la construction à partir de la ligne de commande (ou dans le cadre d'un processus de CI) aboutit à une sortie de test entremêlée avec de nombreuses autres sorties de construction. Avec des phases de construction et d’exécution distinctes, Cedar sépare la sortie afin que la sortie de test soit facile à trouver. Le programme d’essai du Cedar par défaut copie le style d’impression standard "." Cedar a également la possibilité d'utiliser des objets reporter personnalisés. Vous pouvez ainsi obtenir des résultats de sortie comme vous le souhaitez, avec un petit effort.
  • OCUnit est la structure officielle de tests unitaires pour Objective C et est pris en charge par Apple. Apple dispose de ressources pratiquement illimitées, donc s’ils veulent quelque chose, ils le feront. Et, après tout, c’est le bac à sable d’Apple dans lequel nous jouons. Le revers de la médaille, cependant, Est-ce que Apple reçoit chaque jour un ordre de bajillions de demandes d'assistance et de rapports de bogues. Ils sont remarquablement doués pour toutes les gérer, mais ils peuvent ne pas être en mesure de gérer les problèmes que vous signalez immédiatement, Cedar est beaucoup plus récent et moins élaboré que OCUnit, mais si vous avez des questions, des problèmes ou des suggestions, envoyez un message à la liste de diffusion Cedar ([email protected]) et nous ferons tout notre possible pour vous aider. En outre, n'hésitez pas à insérer le code dans Github (github.com/pivotal/cedar) et à ajouter ce que vous pensez être manquant.Nous rendons nos frameworks de test ouverts pour une raison.

  • L'exécution de tests OCUnit sur des appareils iOS peut s'avérer difficile. Honnêtement, je n’ai pas essayé cela depuis assez longtemps, alors c’est peut-être devenu plus facile, mais la dernière fois que j’ai essayé, je ne pouvais tout simplement pas passer les tests OCUnit pour que les fonctionnalités d’UIKit fonctionnent. Lorsque nous avons écrit Cedar, nous nous sommes assurés de pouvoir tester le code dépendant d'UIKit à la fois sur le simulateur et sur les appareils.

Enfin, nous avons écrit Cedar pour les tests unitaires, ce qui signifie que ce n'est pas vraiment comparable à des projets comme UISpec. Cela fait un bon bout de temps que je n'ai pas essayé d'utiliser UISpec, mais j'ai compris qu'il était principalement axé sur la gestion par programme de l'interface utilisateur sur un périphérique iOS. Nous avons spécifiquement décidé de ne pas essayer de faire en sorte que Cedar prenne en charge ces types de spécifications, car Apple était (à l'époque) sur le point d'annoncer UIAutomation.

53
Adam Milligan

Je vais devoir jeter Frank dans le mix des tests d'acceptation. Ceci est une addition assez nouvelle mais a fonctionné excellent pour moi jusqu'à présent. En outre, il est en train de travailler activement, contrairement à icuke et les autres.

8
raidfive

Pour le développement piloté par les tests, j'aime utiliser GHUnit , c'est un jeu d'enfant à configurer et fonctionne également très bien pour le débogage.

5

Grande liste!

J'ai trouvé une autre solution intéressante pour tester l'interface utilisateur d'applications iOS.

Cadre Courgette

Il est basé sur UIAutomation. Le cadre vous permet d’écrire des scénarios centrés sur l’écran avec un style semblable à celui du concombre. Les scénarios peuvent être exécutés dans Simulator et sur le périphérique à partir d'une console (il est compatible avec le CI).

Les assertions sont basées sur les captures d'écran. Cela semble rigide, mais vous obtenez un bon rapport HTML, avec une comparaison d'écran en surbrillance et vous pouvez fournir des masques qui définissent les régions dans lesquelles vous souhaitez une assertion exacte en pixels.

Chaque écran doit être décrit dans CoffeScript et son outil est écrit en Ruby. C'est un peu le cauchemar des polyglottes, mais l'outil fournit une abstraction de Nice pour UIAutomation et lorsque les écrans sont décrits, il est gérable même pour un responsable qualité.

4
mzaks

Je choisirais iCuke pour les tests de réception et Cedar pour les tests unitaires. UIAutomation est un pas dans la bonne direction pour Apple, mais les outils ont besoin d'un meilleur support pour une intégration continue. L'exécution automatique de tests UIAutomation avec Instruments n'est actuellement pas possible, par exemple.

2
SamCee

J'utilise actuellement specta pour les configurations de type rspec et son partenaire (comme mentionné ci-dessus) expecta qui offre une multitude de possibilités de correspondance.

1
Keith Smiley

GHUnit est bon pour les tests unitaires; pour les tests d'intégration, j'ai utilisé UISpec avec un certain succès (github fork ici: https://github.com/drync/UISpec ), mais je suis impatient d'essayer iCuke, car cela promet de l'être une configuration légère, et vous pouvez utiliser la qualité de test Rails, comme RSpec et Cucumber.

1
Rob

J'aime beaucoup OCDSpec2 mais je suis partial, j'ai écrit OCDSpec et j'ai contribué à la seconde.

C'est très rapide, même sur iOS, en partie parce qu'il est construit à partir de la base plutôt que d'être placé sur OCUnit. Il a également une syntaxe RSpec/Jasmine.

https://github.com/ericmeyer/ocdspec2

0
Eric Smith