单元测试自我理解与XCTestCase使用与限制

单元测试自我理解与XCTestCase使用与限制
XCTestCase作为Xcode集成的单元测试框架具有最贴近源代码,不影响源代码,系统独立不增加app的大小。几行代码就能完成一个单元测试,基本能达到条件语句覆盖。不用再等点击一系列按钮之后才能在屏幕上显示出来自己期望的东西,XCTestCase可以很容易的达到全场景测试。
这个是交换NSString字符串中指定两个以0开始编号的位置的符号函数的单元测试用例。

- (void)testSwitchNSStringValue {
    // This is an example of a performance test case.
    [self measureBlock:^{
        // Put the code you want to measure the time of here.
        //[0,15]
        NSString *src =    [CGeneralFunction switchNSStringValue:@"0##1#23####48##6#57#A####B####9#":0:15];
        NSString *dec =                                          @"6##1#23####48##0#57#A####B####9#";
        FLDDLogVerbose(@"src = %@, dec = %@, length = %lu", src, dec, (unsigned long)src.length);
        XCTAssertEqualObjects(src,dec, @"交换失败");
        //[17,25]
        src =              [CGeneralFunction switchNSStringValue:@"0##1#23####48##6#57#A####B####9#":17:25];
        dec =                                                    @"0##1#23####48##6#B7#A####5####9#";
        FLDDLogVerbose(@"src = %@, dec = %@, length = %lu", src, dec, (unsigned long)src.length);
        XCTAssertEqualObjects(src,dec, @"交换失败");
        //[0,31]
        src =              [CGeneralFunction switchNSStringValue:@"0##1#23####48##6#57#A####B####9C":0:31];
        dec =                                                    @"C##1#23####48##6#57#A####B####90";
        FLDDLogVerbose(@"src = %@, dec = %@, length = %lu", src, dec, (unsigned long)src.length);
        XCTAssertEqualObjects(src,dec, @"交换失败");
        //[31,0]
        src =              [CGeneralFunction switchNSStringValue:@"0##1#23####48##6#57#A####B####9C":31:0];
        dec =                                                    @"C##1#23####48##6#57#A####B####90";
        FLDDLogVerbose(@"src = %@, dec = %@, length = %lu", src, dec, (unsigned long)src.length);
        XCTAssertEqualObjects(src,dec, @"交换失败");
        //[31,31]
        src =              [CGeneralFunction switchNSStringValue:@"0##1#23####48##6#57#A####B####9C":31:31];
        dec =                                                    @"0##1#23####48##6#57#A####B####9C";
        FLDDLogVerbose(@"src = %@, dec = %@, length = %lu", src, dec, (unsigned long)src.length);
        XCTAssertEqualObjects(src,dec, @"交换失败");
        //[0,32]
        src =              [CGeneralFunction switchNSStringValue:@"0##1#23####48##6#57#A####B####9C":0:32];
        dec =                                                    @"C##1#23####48##6#57#A####B####90";
        FLDDLogVerbose(@"src = %@, dec = %@, length = %lu", src, dec, (unsigned long)src.length);
        XCTAssertNil(src, @"交换失败");

        //nil
        src =              [CGeneralFunction switchNSStringValue:nil:0:31];
        dec =                                                    @"C##1#23####48##6#57#A####B####90";
        FLDDLogVerbose(@"src = %@, dec = %@, length = %lu", src, dec, (unsigned long)src.length);
        XCTAssertNil(src, @"交换失败");

    }];

}

看到这个单元测试简捷的实现了该函数的全场景覆盖,包括边界测试场景,经过这种单元测试,可以达到鲁棒性超强的代码。

XCTestCase也对被测试函数的要求,只有达到符合XCTestCase测试标准的函数才能使用这种单元测试。对表格函数建议不要直接使用XCTestCase测试,但是可以对局部包含的函数采用XCTestCase测试。
XCTestCase具体的使用具体详细见附件中的文档。

XCTestCase作为XCode自带的单元测试具有一下特征:

  1. 只能通过参数传递参数,测试类方法的返回值是否达到期望的结果。

  2. 不能通过测试类方法的调用后对全局变量的影响。

  3. 不能通过测试类方法中有直接读取UI元素(如:文本框)并且对结果产生影响的类方法。

  4. 不适合直接测试表格UITabeView,若测试UITabeView需要要用到第三方库OCMock,工作量很大,并且源代码修改为表格数据源和控制器分开,这样也不适合大多少OC的习惯。这样写测试用例还不如直接运行UI设置断点调试呢。

  5. NSString和char数组的转换及char数组交换不能进行单元测试,否者会产生崩溃。

  6. 不能测试无返回值的类函数。
    软件开发工程师们(当然包括你我)最开始学习程序编写时,最喜欢干的事情就是编写一段代码,然后运行观察结果是否正确。如果不对就返回代码检查错误,或者是加入断点或者输出跟踪程序并找出错误,然后再次运行查看输出是否与预想一致。如果输出只是控制台的一个简单的数字或者字符那还好,但是如果输出必须在点击一系列按钮之后才能在屏幕上显示出来的东西呢?难道我们就只能一次一次地等待编译部署,启动程序然后操作UI,一直点到我们需要观察的地方么?而且程序有种习惯就是只测试正常情况,不测试所有情况就认为自己的代码ok了。单元测试就是为减少无谓的体力劳动和方便测试所有场景达到语句覆盖(所有判断分之测试,无判断的测试也没有任何意义)测试的目的。
    在代码中调用我们之前想检查的代码,并将运行的结果与我们的设想结果在程序中进行比较,如果一致,则说明了我们的代码没有问题,是按照预期工作的。单元测试这就是对这种思想一种实现方式。简言就是首先明确你要让函数或方法实现(行为)什么功能(期望),单元测试帮你检查你的行为能不能实现所有情况下的期望。只需要对对应类建立一个测试类,在测试用例只需要在调用函数时传递给它你需要测试的条件参数,就可以对结果进行判断了。工作量很小。本质是函数测试,不能测试UI。
    测试驱动开发(Test Driven Development,以下简称TDD)是保证代码质量的不二法则是第一代敏捷方法。生活中类似的例子来说明TDD的必要性:有经验的砌砖师傅总是会先拉一条垂线,然后沿着线砌砖,因为有直线的保证,因此可以做到笔直整齐;而新入行的师傅往往二话不说直接开工,然后在一阶段完成后再用直尺垂线之类的工具进行测量和修补。TDD的好处不言自明,因为总是先测试,再编码,所以至少你的所有代码的public部分都应该含有必要的测试。测试驱动开发的优点是十分贴近源码,又不影响代码,可以边写测试用例边写代码,工作两很较少,对代码质量提高很有效。不像行为驱动开发需要开始抽象出一套系统进行行为和期望的描述。
    单元测试的最终目的是:反复测试测试直到各种边界和测试都进行完毕,此时我们便可以得到一个具有测试保证,鲁棒性超强的产品代码。在我们之后的开发中,因为你有这些测试的保证,你可以大胆重构这段代码或者与之相关的代码,最后只需要保证项目处于绿灯状态,你就可以保证代码没重构没有出现问题。所谓断言,就是判断输入的条件是否满足。如果不满足,则抛出错误并输出预先规定的字符串作为提示。XCTestCase测试的函数要再被测试类的.h文件里要有声明。XCTestCase所有的测试都是由断言完成的。
    XCode5.0及以后版本在建立工程时会自动建立XCTestCase框架及测试例子。

    XCTestCase真机调试使用,单元测试部分需要的配置:
    1.Edit Scheme…,设置test为Debug。设置Executable为和run中的名称相同。
    这里写图片描述
    这里写图片描述

2.设置研发者证书。
这里写图片描述
3.设置测试target的和原工程的信息属性一直,特别时Bundle identifier要一致或和配置的证书指定Bundle identifier一直(若使用两个不同的证书的情况)
这里写图片描述
这里写图片描述

只需要在工程的Tests目录下点击新建文件,选择iOS->Souce->Test Case Class就能建立测试类,注意通常测试类以Tests结束,测试用例以test单词开始,一个测试用例可以有多个断言。详细参考文章:http://blog.csdn.net/chaoyuan899/article/details/25779295
这里写图片描述

XCTestCase作为XCode自带的单元测试具有一下特征:
1.只能通过参数传递参数,测试类方法的返回值是否达到期望的结果。
2.不能通过测试类方法的调用后对全局变量的影响。
3.不能通过测试类方法中有直接读取UI元素(如:文本框)并且对结果产生影响的类方法。
4.不适合直接测试表格UITabeView,若测试UITabeView需要要用到第三方库OCMock,工作量很大,并且源代码修改为表格数据源和控制器分开,这样也不适合大多少OC的习惯。这样写测试用例还不如直接运行UI设置断点调试呢。
5.NSString和char数组的转换及char数组交换不能进行单元测试,否者会产生崩溃。
6.不能测试无返回值的类函数。
点XCode工具栏的Product->Test可以启动所有测试用例。带绿勾的时通过的例子,带红叉的时单元测试失败的例子,没有运行过的新测试用例是灰色的菱形图标。测试用例可以点绿勾或红叉直接启动该测试用例。
这里写图片描述
XCTestCase使用的例子:
1.公有类函数,由于这类函数都是与UI没有直接关系,只是与输入参数有关,通常有输出参数,这类函数是最适合采用单元测试测试的函数。switchNNStringValue函数的功能对NSString字符串的两个指定位置的字符进行交换。简单吧?3行代码测试一个分支,所以工作量很小,对项目进度影响。经过单元测试减少的问题单修改的时间远比使用它所花的时间长。

import “CGeneralFunction.h”

这里写图片描述

2.普通函数测试用例:

import “LoginViewController.h”

import “GlobalVariable.h”

import “UITextFieldValue.h”

这里写图片描述

3.不能使用测试场景:
建立页面控制器页面(UIViewController及子类)后通过,给它的文本框赋值,当调用函数根本就不能影响类函数的文本框的值,并且是空指针。实际上这样的类函数就不能测试。

实际上就是你给它申请一个文本框也影响不了类函数种所获取到的文本框的值为空。所以单元测试时,只要输入参数才能影响类函数种的处理,就是像要用单元测试就要按照单元测试的规则写函数才能测试。

单元测试用例不能拿全局变量当判断条件,因为类函数再调用完并不能影响测试用例种的全局变量,可见类函数和测试用例应该属于不同的模块,全局变量虽然同名,但是确实两个模块不同的全局变量。

XCTestCase崩溃的例子:
1.表格处理函数在控制器里直接实现用OCMock模拟时崩溃。

2.NSString和char数组的转换及char数组交换不能进行单元测试,否者会产生崩溃。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值