TDD(测试驱动开发 Test Driven Development),相比传统的开发流程,会先写测试,待测试通过再实际开发功能模块。这样的好处是在你使用这些已经测试过的功能时,不用担心他们的可用性。
BDD(行为驱动开发 Behavior Driven Development),相比TDD,相关测试代码更加集中,也更加简单易懂
PS:本文中主要介绍的是ReactiveCocoa的测试方法
1.模型测试
`- (**void**)testPersonModel`
`{`
` NSString ***string** = @"{\"uname\":\"jack\",\"pic\":\"[http://krplus-cdn.b0.upaiyun.com/common-module/common-header/images/logo.png\](http://krplus-cdn.b0.upaiyun.com/common-module/common-header/images/logo.png%5C)"}";
Person *a = [Person data:[**string** jsonDictionary]];`
XCTAssertNotNil(a, @"model is nil");
` XCTAssertNotNil(a.name, @"person has not a name!");`
XCTAssertNotNil(a.avatar, @"person has not a avatar!");
`}`
2.接口测试
`- (**void**)testJsonAPI`
`{`
` *// 使用 measureBlock 方法可以记录该测试的耗时*
[**self** measureBlock:^{
NSString *urlStr = @"[http://xiaoliao.sinaapp.com/index.php/Api369/index/pad/0/sw/1/cid/mm/lastTime/1441598591](http://xiaoliao.sinaapp.com/index.php/Api369/index/pad/0/sw/1/cid/mm/lastTime/1441598591)";
NSString *newUrlStr = [urlStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL *url = [NSURL URLWithString:newUrlStr];
NSURLRequest *request = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:10];
NSURLResponse *response = nil;
NSError *error = nil;
NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
NSString *aString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
XCTAssertNotNil(aString, @"json is nil");
NSArray *jsonArray = [aString jsonArray];
XCTAssertNotNil(jsonArray, @"jsonArray is empty!");`
[jsonArray enumerateObjectsUsingBlock:^(NSDictionary *json, NSUInteger idx, BOOL *stop) {
` Person *a = [Person data:json];`
XCTAssertNotNil(a, @"model is nil");
` XCTAssertNotNil(a.name, @"person has not a name!");`
XCTAssertNotNil(a.avatar, @"person has not a avatar!");
}];
` }];`
`}`
使用 kiwi框架
1.ViewModel的测试
SPEC_BEGIN(GinLoginViewModelSpec)
describe(@"GinLoginViewModel", ^{
__block GinLoginViewModel *loginVM;
//在scope内的每个it之前调用一次,对于context的配置代码应该写在这里
beforeEach(^{
loginVM = [[GinLoginViewModel alloc] init];
});
//在scope内的每个it之后调用一次,用于清理测试后的代码
afterEach(^{
loginVM = nil;
});
context(@"when username is 123456 and password is 123456", ^{
__block BOOL result = NO;
it(@"should return signal that value is NO", ^{
loginVM.username = @"123456";
loginVM.password = @"123456";
[[loginVM isValidUsernameAndPasswordSignal] subscribeNext:^(NSNumber *isValid) {
result = [isValid boolValue];
}];
[[theValue(result) should] beNo];
});
});
context(@"when username is 15511112222 and password is 123456", ^{
__block BOOL result = NO;
it(@"should return signal that value is YES", ^{
loginVM.username = @"15511112222";
loginVM.password = @"123456";
[[loginVM isValidUsernameAndPasswordSignal] subscribeNext:^(NSNumber *isValid) {
result = [isValid boolValue];
}];
[[theValue(result) should] beYes];
});
});
});
SPEC_END
2.ViewController测试
SPEC_BEGIN(GinLoginViewControllerSpec)
describe(@"GinLoginViewController", ^{
__block GinLoginViewController *loginVC;
__block NSString *username = @"15511112222";
__block NSString *password = @"abc123456";
beforeEach(^{
loginVC = [[GinLoginViewController alloc] init];
[loginVC view];
});
afterEach(^{
loginVC = nil;
});
context(@"bind ViewModel", ^{
it(@"textfiled bind success", ^{
loginVC.username.text = username;
loginVC.password.text = password;
[loginVC.username sendActionsForControlEvents:UIControlEventEditingChanged];
[loginVC.password sendActionsForControlEvents:UIControlEventEditingChanged];
[[loginVC.loginVM.username should] equal:loginVC.username.text];
[[loginVC.loginVM.password should] equal:loginVC.password.text];
});
it(@"command bind success", ^{
[[loginVC.nextStep.rac_command should] equal:loginVC.loginVM.loginCommand];
});
});
});
SPEC_END
原文作者: [Ginhoor]
原文链接:https://blog.csdn.net/ginhoor/article/details/48290175
网友评论