关于iOS TDD&BDD的学习与使用

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Ginhoor/article/details/48290175

TDD(测试驱动开发 Test Driven Development),相比传统的开发流程,会先写测试,待测试通过再实际开发功能模块。这样的好处是在你使用这些已经测试过的功能时,不用担心他们的可用性。

BDD(行为驱动开发 Behavior Driven Development),相比TDD,相关测试代码更加集中,也更加简单易懂

相关链接:

TDD的iOS开发初步以及Kiwi使用入门

http://onevcat.com/2014/02/ios-test-with-kiwi/

Kiwi 使用进阶 Mock, Stub, 参数捕获和异步测试

http://onevcat.com/2014/05/kiwi-mock-stub-test/


PS:本文中主要介绍的是ReactiveCocoa的测试方法


使用OCUnit Test 

1.模型测试

- (void)testPersonModel
{
    NSString *string = @"{\"uname\":\"jack\",\"pic\":\"http://krplus-cdn.b0.upaiyun.com/common-module/common-header/images/logo.png\"}";

    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";

        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 15558066089 and password is 123456", ^{       
          __block BOOL result = NO;       
          it(@"should return signal that value is YES", ^{  
              loginVM.username = @"15558066089";          
              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 = @"15558066089";
    __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

猜你喜欢

转载自blog.csdn.net/Ginhoor/article/details/48290175