我最近开始学习 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 进行集成,效果很好。
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];
});
});
});
有一个相对较新的项目叫做uispec,它的灵感来自于 RSpec 的测试 DSL。示例规范如下所示:
#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 为 Objective-C 创建了一个名为Cedar的 BDD 框架,该框架同时针对 Cocoa 和 Cocoa Touch。它以与 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(SenTestingKit,包含在 Xcode 中)中的宏是如何实现的。
在您自己的单元测试包中,您可以实现一个类别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 做到了这一点。