27 votes

BDD dans Objective-C

J'ai récemment commencé à apprendre Objective-C et à écrire mes tests à l'aide d'OCUnit fourni avec Xcode.

Je suis un programmeur Ruby de longue date et j'ai l'habitude de RSpec et Cucumber - de beaux frameworks BDD.

Existe-t-il un cadre BDD décent à utiliser dans Objective-C? Je manque mes «devrais :)

21voto

djromero Points 11713

J'utilise Kiwi Library Quick pour intégrer, fonctionne assez bien.

De leur github :

 describe(@"Team", ^{
    context(@"when newly created", ^{
        it(@"should have a name", ^{
            id team = [Team team];
            [[team.name should] equal:@"Black Hawks"];
        });

        it(@"should have 11 players", ^{
            id team = [Team team];
            [[[team should] have:11] players];
        });
    });
});
 

17voto

Nathan de Vries Points 10895

Il y a un projet relativement nouveau appelé uispec qui a été inspiré par les tests DSL de RSpec. L'exemple de spécification ressemble à ceci:

 #import "DescribeEmployeeAdmin.h"
#import "SpecHelper.h"

@implementation DescribeEmployeeAdmin

-(void)before {
  //login as default admin before each example
  [SpecHelper loginAsAdmin];
}

-(void)after {
  //logout after each example
  [SpecHelper logout];
}

-(void)itShouldHaveDefaultUsers {
  //Check that all default users are in list
  [[app.tableView.label text:@"Larry Stooge"] should].exist;
  [[app.tableView.label text:@"Curly Stooge"] should].exist;
  [[app.tableView.label text:@"Moe Stooge"] should].exist;
}

-(void)itShouldAddAUser {
  //Click the + button
  [app.navigationButton touch];

  //Set the form fields.
  //Also ".with" is optional so we here we can show the different syntax
  [[app.textField.with placeholder:@"First Name"] setText:@"Brian"];
  [[app.textField.with placeholder:@"Last Name"] setText:@"Knorr"];
  [[app.textField.with placeholder:@"Email"] setText:@"b@g.com"];
  [[app.textField placeholder:@"Username"] setText:@"bkuser"];
  [[app.textField placeholder:@"Password"] setText:@"test"];
  [[app.textField placeholder:@"Confirm"] setText:@"test"];

  //Click the Save button
  [[app.navigationButton.label text:@"Save"] touch];

  //Make sure the error alert view doesn't appear
  [app timeout:1].alertView.should.not.exist;

  //User list should now have a new entry
  [[app.tableView.label text:@"Brian Knorr"] should].exist;
}

@end
 

Gardez à l'esprit que je ne l'ai jamais utilisé, il y a donc une chance qu'il ne réponde pas exactement à vos besoins. Mais à tout le moins, vous pourrez utiliser la base de code comme source d'inspiration pour écrire votre propre framework de test.

13voto

Don McCaughey Points 4433

Adam Milligan de Pivotal Labs a créé un cadre BDD pour Objective-C appelé Cedar qui cible à la fois Cocoa et Cocoa Touch. Il utilise des blocs d'une manière similaire à RSpec. Voici un exemple de spécification:

 SPEC_BEGIN(FooSpecs)

sharedExamplesFor(@"a similarly-behaving thing", ^(NSDictionary *context) {
    it(@"should do something common", ^{
        ...
    });
});

NSDictionary *context = [NSDictionary dictionary];

describe(@"Something that shares behavior", ^{
    itShouldBehaveLike(@"a similarly-behaving thing", context);
});

describe(@"Something else that shares behavior", ^{
    itShouldBehaveLike(@"a similarly-behaving thing", context);
});

SPEC_END
 

8voto

Chris Hanson Points 34485

Jetez un oeil à la façon dont l' STAssert macros dans OCUnit (SenTestingKit, fourni avec Xcode) sont mis en œuvre.

Dans votre propre unité de test bundle, vous pouvez mettre en œuvre une catégorie sur NSObject d'ajouter des méthodes comme un hypothétique -shouldBeValid qui serait ensuite appeler la même réussite/échec des machines que l' STAssert macros faire maintenant.

Dans le cas où vous n'êtes pas intimement familier avec le préprocesseur C...

Vous pourriez avoir à utiliser un #define pour vos macros à passer à travers les valeurs de droite pour __FILE__ et __LINE__ lors de votre BDD tests échouent. Par exemple, vous pourriez avoir à faire quelque chose comme ceci:

@interface NSObject (BehaviorDrivenDevelopment)
- (void)shouldBeValidInFile:(const char *)file line:(int)line;
@end

#define shouldBeValid  shouldBeValidInFile:__FILE__ line:__LINE__

De cette façon, vous serait de l'appeler comme ceci:

[[someObject methodUnderTest:argument] shouldBeValid];

Le code que le compilateur voit seront présent:

[[someObject methodUnderTest:argument] shouldBeValidInFile:__FILE__ line:__LINE__];

L' __FILE__ et __LINE__ macros du préprocesseur va s'étendre vers le fichier en cours et dans votre source de test de fichier.

De cette façon, lorsque vous avez un test en échec, il peut transmettre des informations appropriées à l'SenTestingKit à envoyer à Xcode. L'échec s'afficher correctement dans les Résultats de la compilation de la fenêtre, et en cliquant dessus vous amène à l'exact emplacement de l'échec dans vos tests.

3voto

user1829404 Points 41

Vous pouvez jeter un œil à BDD De l'idée à l'application où vous verrez un exemple d'utilisation de calebasse.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X