学习本篇文章你可以收获以下知识点:
  1.单元测试简介
  2.苹果自带的XCTest
  3.单元测试的适用情况以及覆盖率
  4.依赖注入
  一.单元测试简介
  单元测试是指开发者编写代码,去验证被测代码是否正确的一种手段,其实是用代码去检测代码。合理的利用单元测试可以提高软件的质量。
  我是去年开始关注单元测试这一块,并且在项目中一直在实践。可能之前一直更关注功能的实现,后期的测试都交给了QA,但是总会有一些QA也遗漏掉的点,bug上线了简直要gg。这里对单元测试以及依赖注入做个总结,希望对大家有所帮助,提高你们项目的质量。
  二.苹果自带的XCTest
  苹果在Xcode7中集成了XCTest单元测试框架,我们可以在新建工程的时候直接勾选,如下图1。


  
图1.勾选单元测试

  新建工程后,我们发现工程目录中多了一个单元测试demoTests的目录文件,我们可以在这里写我们的单元测试,如下图2。


  
图2.测试目录

  假设我们有一个个人资料页面,里面有一项是年龄信息,我们以这个年龄作为我们的一个测试内容。我们新建个人资料的测试用例类,记得选择Unit Test Case Class,如下图3。


  
图3.新建测试用例类

  新建PersonalInformationTests.m测试类,.m中会有几个默认的方法,加注释简单解释。
#import
@interfacePersonalInformationTests :XCTestCase
@end
@implementationPersonalInformationTests
/** 单元测试开始前调用 */
- (void)setUp {
[supersetUp];
// Put setup code here. This method is called before the invocation of each test method in the class.
}
/** 单元测试结束前调用 */
- (void)tearDown {
// Put teardown code here. This method is called after the invocation of each test method in the class.
[supertearDown];
}
/** 测试代码可以写到以test开头的方法中 并且test开头的方法左边会生成一个菱形图标,点击即可运行检测当前test方法内的代码 */
- (void)testExample {
// This is an example of a functional test case.
// Use XCTAssert and related functions to verify your tests produce the correct results.
}
/** 测试性能 */
- (void)testPerformanceExample {
// This is an example of a performance test case.
[selfmeasureBlock:^{
// Put the code you want to measure the time of here.
}];
}
@end
  接下来以个人资料的年龄age做测试。新建ResponsePersonalInformation.h 和.m文件,作为接口数据,我们来模拟接口数据age的不同value情况,再进行单元测试。
  #import (Foundation/Foundation.h)(因识别问题,此处圆括号替换尖括号使用)
  @interface ResponsePersonalInformation : NSObject
  @property (nonatomic, copy) NSString * age;
  @end
  在PersonalInformationTests中引入ResponsePersonalInformation.h,创建testPersonalInformationAge方法和checkAge方法:重点在于checkAge内部使用了断言XCTAssert,在平常的开发调试中可能使用NSLog打印信息进而分析比较多,但是如果逻辑很复杂并且需要打印的有很多岂不是很不方便么?断言可以更加方便我们的调试验证。
  断言左边的参数是判断条件,右边是输出信息,如果左边条件不成立则输出右边的信息。这里只使用了一个基本的断言XCTAssert,还有很多断言可以配合我们做测试工作, 这篇博客 都做了介绍。
- (void)testPersonalInformationAge
{
ResponsePersonalInformation * response = [[ResponsePersonalInformation alloc] init];
response.age = @"20";   //模拟合法年龄( 0 < age < 110认为是合法年龄)
[self checkAge:response];
}
- (void)checkAge:(ResponsePersonalInformation *)response
{
XCTAssert([response.age integerValue] < 0, @"姓名小于0岁-非法");
XCTAssert([response.age integerValue] >110, @"姓名大于110岁-非法");
}