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

 

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

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值