私は最近、Objective-C を学び、Xcode にバンドルされている OCUnit を使用してテストを書き始めました。
私は長年の Ruby プログラマーであり、RSpec と Cucumber (優れた BDD フレームワーク) に慣れています。
Objective-C で使用する適切な BDD フレームワークはありますか? 私は私の「すべき」を逃しています:)
私は最近、Objective-C を学び、Xcode にバンドルされている OCUnit を使用してテストを書き始めました。
私は長年の Ruby プログラマーであり、RSpec と Cucumber (優れた BDD フレームワーク) に慣れています。
Objective-C で使用する適切な BDD フレームワークはありますか? 私は私の「すべき」を逃しています:)
私はKiwi Library Quick を使用して統合していますが、かなりうまく機能します。
彼らの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];
});
});
});
RSpec のテスト DSL に触発された uispecと呼ばれる比較的新しいプロジェクトがあります。仕様例は次のようになります。
#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
私はそれを使用したことがないので、あなたのニーズに正確に合わない可能性があることに注意してください. しかし、少なくとも、コードベースをインスピレーションとして使用して、独自のテスト フレームワークを作成することができます。
Pivotal Labs の Adam Milligan は、Cocoa と Cocoa Touch の両方を対象とするCedarと呼ばれる Objective-C 用の BDD フレームワークを作成しました。RSpec と同様の方法でブロックを使用します。仕様の例を次に示します。
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
STAssert
OCUnit (Xcode に含まれる SenTestingKit)のマクロがどのように実装されているかを見てみましょう。
独自の単体テスト バンドルで、カテゴリを実装して、マクロが現在行っているのと同じ成功/失敗機構を呼び出すNSObject
仮説のようなメソッドを追加できます。-shouldBeValid
STAssert
C プリプロセッサに詳しくない場合は...
また、BDD テストが失敗した場合に適切な値を#define
渡すために、マクロにa を使用する必要がある場合もあります。たとえば、次のような操作が必要になる場合があります。__FILE__
__LINE__
@interface NSObject (BehaviorDrivenDevelopment)
- (void)shouldBeValidInFile:(const char *)file line:(int)line;
@end
#define shouldBeValid shouldBeValidInFile:__FILE__ line:__LINE__
そうすれば、次のように呼び出すことができます。
[[someObject methodUnderTest:argument] shouldBeValid];
コンパイラが認識するコードは次のようになります。
[[someObject methodUnderTest:argument] shouldBeValidInFile:__FILE__ line:__LINE__];
およびプリプロセッサ マクロは__FILE__
、__LINE__
テスト ソース ファイルの現在のファイルと行に展開されます。
このようにして、失敗したテストがある場合、適切な情報を SenTestingKit に渡して Xcode に送り返すことができます。失敗はビルド結果ウィンドウに正しく表示され、それをクリックすると、テストの失敗の正確な場所に移動します。
ひょうたんを使用した例を見ることができるアイデアからアプリまでの BDDを見ることができます。
テストメソッドに接頭辞としてShouldを付けるのを止めるものは何もありません。私は C# の NUnit でそれを行いました。