iOS开发——单元测试

发表于:2016-06-07来源:cocoa China作者:Sindri的小巢点击数: 标签:单元测试
维基百科对单元测试的定义如下: 在计算机编程中,单元测试(英语:Unit Testing)又称为模块测试, 是针对程序模块(软件设计的最小单位)来进行正确性检验的测试工作。程序单元是

  前言

  维基百科对单元测试的定义如下:

  在计算机编程中,单元测试(英语:Unit Testing)又称为模块测试, 是针对程序模块(软件设计的最小单位)来进行正确性检验的测试工作。程序单元是应用的最小可测试部件。

  在过程化编程中,一个单元就是单个程序、函数、过程等;对于面向对象编程,最小单元就是方法,包括基类(超类)、抽象类、或者派生类(子类)中的方法。

  根据不同场景,单元的定义也不一样,通常我们将C语言的单个函数或者面向对象语言的单个类视作测试的单元。在使用单元测试的过程中,我们要知道这一点:

  单元测试并不是为了证明代码的正确性,它只是一种用来帮助我们发现错误的手段

  单元测试不是万能药,它确实能帮助我们找到大部分代码逻辑上的bug,同时,为了提高测试覆盖率,这能逼迫我们对代码不断进行重构,提高代码质量等。

  内置单元测试框架

  在Xcode4.x中集成了测试框架OCUnit,根据测试的目的大致可以将单元测试分为这三类:

  性能测试:测试代码执行花费的时间

  逻辑测试:测试代码执行结果是否符合预期

  异步测试:测试多线程操作代码

  在我们新建项目的时候,已经默认选择创建单元测试的框架,除了Unit Tests之外还有一个UI Tests是iOS9推出的新特性,针对UI界面的单元测试框架。在创建项目之后,会自动生成一个appName+Tests的文件夹目录,下面存放着单元测试的文件

  一个标准的测试类文件代码如下。其中setUp会在每一个测试用例开始前调用,用来初始化相关数据;tearDown在测试用例完成后调用,可以用来释放变量等结尾操作;testPerformanceExample中的会将方法中的block代码耗费时长打印出来;最后的testExample 用来执行我们需要的测试操作,正常情况下,我们不使用这个方法,而是创建名为test+测试目的的方法来完成我们需要的操作:

  测试用例

  在每个测试用例方法的左侧有个菱形的标记,点击这个标记可以单独的运行这个测试方法。如果测试通过没有发生任何断言错误,那么这个菱形就会变成绿色勾选状态。使用快捷键command+U直接依次调用所有的单元测试。另外,可以在左侧的文件栏中选中单元测试栏目,然后直观的看到所有测试的结果。同样的点击右侧菱形位置的按钮可以运行单个测试方法或者文件:

  单元测试总览

  另外,为了保证单元测试的正确性,我们应当保证测试用例中只存在一个类或者只发生一个类变量的属性修改。下面是我们测试中常用的宏定义:

  XCTAssertNotNil(a1, format…) 当a1不为nil时成立

  XCTAssert(expression, format...) 当expression结果为YES成立

  XCTAssertTrue(expression, format...) 当expression结果为YES成立;

  XCTAssertEqualObjects(a1, a2, format...) 判断相等,当[a1 isEqualTo: a2]返回YES的时候成立

  XCTAssertEqual(a1, a2, format...) 当a1==a2返回YES时成立

  XCTAssertNotEqual(a1, a2, format...) 当a1!=a2返回YES时成立

  逻辑测试

  笔者新建了一个用以测试的model类,该类提供了三个接口。需要注意的是,在逻辑测试的某个操作步骤前后,应该有对应的数据发生了改变,这样才能够方便我们进行测试:

  @interface LXDTestsModel : NSObject

  @property (nonatomic, readonly, copy) NSString * name;

  @property (nonatomic, readonly, strong) NSNumber * age;

  @property (nonatomic, readonly, assign) NSUInteger flags;

  + (instancetype)modelWithName: (NSString *)name age: (NSNumber *)age flags: (NSUInteger)flags;

  - (instancetype)initWithDictionary: (NSDictionary *)dict;

  - (NSDictionary *)modelToDictionary;

  @end

  在测试用例中,我定义了一个testModelConvert方法用来测试模型跟json之间的转换是否正确:

  - (void)testModelConvert

  {

  NSString * json = @"{\"name\":\"SindriLin\",\"age\":22,\"flags\":987654321}";

原文转自: http://www.cocoachina.com/ios/20160607/16612.html