objective-c bdd

objective c - BDD en Objective-C



(6)

Adam Milligan de Pivotal Labs ha creado un marco BDD para Objective-C llamado Cedar que se enfoca tanto en Cocoa como en Cocoa Touch. Utiliza bloques de manera similar a RSpec. Aquí hay una especificación de ejemplo:

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

Recientemente comencé a aprender Objective-C y escribo mis pruebas usando OCUnit que viene con Xcode.

Soy programador de Ruby desde hace mucho tiempo y estoy acostumbrado a RSpec y Cucumber: agradables frameworks BDD.

¿Hay un marco de BDD decente para usar en Objective-C? Me estoy perdiendo mis ''debería''


Estoy usando Kiwi Library Quick para integrar, funciona bastante bien.

De su 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]; }); }); });


Hay un proyecto relativamente nuevo llamado uispec que se inspiró en las pruebas DSL de RSpec. La especificación de ejemplo se ve así:

#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:@"[email protected]"]; [[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

Tenga en cuenta que nunca lo he usado, por lo que existe la posibilidad de que no se ajuste exactamente a sus necesidades. Pero al menos, podrás usar el código base como inspiración para escribir tu propio marco de prueba.


No hay nada que le impida prefijar su método de prueba con Should. Lo hice con NUnit en C #.


Observe cómo se STAssert macros STAssert en OCUnit (SenTestingKit, incluido con Xcode).

En su propio paquete de prueba de unidad, podría implementar una categoría en NSObject para agregar métodos como un hipotético -shouldBeValid que luego llamaría la misma maquinaria de aprobación / falla que STAssert macros STAssert ahora.

En caso de que no esté familiarizado con el preprocesador C ...

Es probable que también tenga que usar #define para que sus macros pasen a través de los valores correctos para __FILE__ y __LINE__ cuando sus pruebas BDD fallan. Por ejemplo, puede que tengas que hacer algo como esto:

@interface NSObject (BehaviorDrivenDevelopment) - (void)shouldBeValidInFile:(const char *)file line:(int)line; @end #define shouldBeValid shouldBeValidInFile:__FILE__ line:__LINE__

De esa forma lo invocarías así:

[[someObject methodUnderTest:argument] shouldBeValid];

El código que ve el compilador será este:

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

Las macros del preprocesador __FILE__ y __LINE__ se expandirán al archivo y línea actuales en el archivo fuente de prueba.

De esta manera, cuando tiene una prueba que falla, puede pasar la información apropiada a SenTestingKit para enviarla a Xcode. La falla se mostrará correctamente en la ventana Resultados de la compilación, y hacer clic en ella te llevará a la ubicación exacta de la falla en tus pruebas.