3.异步测试
  在Xcode6之前的版本里面并没有内置XCTest,想使用Xcode测试的只能是在主线程的RunLoop里面使用一个while循环,然后一直等待响应或者直到timeout.(Xcode6中添加了新特性:XCTestExpectation和性能测试:特性是内建的对于异步测试的支持,测试能够为了确定的合适的条件等待一个指定时间长度,而不需要求助于GCD)
  model文件:
  (void)testAsync
  {//异步测试
  NSDictionary*dict=@{
  @"name":@"MrLi",
  @"age":@28,
  @"flags":@987
  };
  TestModel1*model=[[TestModel1alloc]initWithDictionary:dict];
  XCTAssertNotNil(model);
  [modelasyncConvertToData];
  while(model.data==nil){
  CFRunLoopRunInMode(kCFRunLoopDe
  faultMode,0.01,YES);
  NSLog(@"waiting");
  XCTAssertNotNil(model.data);
  NSLog(@"convertfinish%@",model.data);
  }
  model文件:
  (void)asyncConvertToData
  {
  dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0),^{
  NSDictionary*modelJSON=nil;
  for(NSIntegeridx=0;idx<20;
  idx++){
  modelJSON=[selfmodelToDictionary];
  [selfsetValuesForKeysWithDictionary
  :modelJSON];
  [NSThreadsleepForTimeInterval:0.001];
  }
  _data=[NSJSONSerializationdataWith
  JSONObject:modelJSONoptions:NSJSON
  WritingPrettyPrintederror:nil];
  });
  }
  e.g.新方法
  在Xcode6里,苹果以XCTestExpection类的方式向XCTest框架里添加了测试期望(testexpection)。当我们实例化一个测试期望(XCTestExpectation)的时候,测试框架会预计它在之后的某一时刻被实现。终的程序完成代码块中的测试代码会调用XCTestExpection类中的fulfill方法来实现期望。
  我们让测试框架等待(有时限)测试期望通过XCTestCase的waitForExpectationsWithTimeout:handler:方法实现。如果完成处理的代码在指定时限里执行并调用了fulfill方法,那么说明所有的测试期望在此期间都已经被实现。此方法中的handler的参数其实是一个block,block中若是写有代码,代码执行的条件(满足其中之一可执行):a、所有期望在指定的时间内都以实现;b、期望在指定的时间内没有实现(此时会报错,但是block里面的方法会执行)。
  代码:
  (void)testAsyncOutTime{
  XCTestExpectation*ex=[selfexpectationWithDescription:@"wgj001"];
  NSURL*url=[NSURLURLWithString
  :@"https://www.baidu.com"];
  NSURLSession*session=[NSURLSessionsessionWithConfiguration:[NSURLS
  essionConfigurationdefaultSession
  Configuration]];
  NSURLRequest*request=[NSURLRequest
  requestWithURL:url];
  NSURLSessionTask*task=[session
  dataTaskWithRequest:requestcompletion
  Handler:^(NSData*_Nullabledata,
  NSURLResponse*_Nullableresponse,
  NSError*_Nullableerror){
  NSLog(@"url请求完成");
  [exfulfill];//如果完成处理的代码在指定
  时限里执行并调用了fulfill方法,那么
  说明所有的测试期望在此期间都已经被实现
  }];
  [taskresume];
  [selfwaitForExpectationsWithTimeout:
  1handler:^(NSError*_Nullableerror){
  if(error){
  NSLog(@"wati:%@",error);
  }
  断言:
  1、XCTFail(...):参数可有可无,若有则须是字符串,参数为错误的描述。无条件的都是测试失败。在测试驱动里有这么个情况,你定义了测试方法,但是没有给出具体的实现。那么你不会希望这个测试能通过的。一般被用作一个占位断言。等你的测试方法完善好了之后再换成贴近你的测试的断言。有或者,在某些情况下else了之后是不应该出现的情况。那么这个时候可以把XCTFail放在这个else里面。
  2、XCTAssertNil(expression,...)/XCTAssertNotNil(expression,...):判断给定的表达式值是否为nil,XCTAssertNil(表达式为nil的时候通过),XCTAssertNotNil(表达式不为nil的时候通过),其中...是错误描述,为字符串类型,下面的表达式中的意思都是一样的。
  3、XCTAssert(expression,...):如果expression(表达式)执行的结果为true的话,这个测试通过。否则,测试失败,并在console中输出后面的format字符串.
  4、后面基于XCTAssert演化出来的断言,不仅可以满足测试的需求而且可以更好更明确的表达出你要测试的是什么。好是使用这些演化出来的断言:
  a.Bool测试
  对于bool型的数据,或者只是简单的bool型的表达式,使用XCTestAssertTrue或者XCTestAssertFalse:
  XCTAssertTrue(expression,format...)
  XCTAssertFalse(expression,format...)
  b.相等测试
  测试两个数值的值是否相等使用XCTAssert[Not]Equal:
  XCTAssertEqual(expression1,
  expression2,format...)
  XCTAssertNotEqual(expression1,
  expression2,format...);
  判断两个对象用:XCTAssertEqualObjects(expression1,expression2,...)和XCTAssertNotEqualObjects(expression1,expression2,...)
  在Double、Float型数据的对比中使用XCTAssert[Not]EqualWithAccuracy来处理浮点精度的问题:
  XCTAssertEqualWithAccuracy(expression1,
  expression2,accuracy,format...)
  XCTAssertNotEqualWithAccuracy(expression1,
  expression2,accuracy,format...)
  e.g.XCTAssertEqualWithAccuracy(12,14,1,@"wgj"),则不通过,因为12和14的差别已经超过了设定的值1。
  XCTAssertGreaterThan[OrEqual]&XCTAssertLessThan[OrEqual],和下面的条件操作符比较的是一个意思==with>,>=,<,以及<=
  5、抛异常:
  a.
  XCTAssertThrows(expression,...):表达式抛异常时,通过;反之,不通过。e.g.XCTAssertThrows([modelonlyTest],@"wgj01");方法在model中只有声明但没有实现,此表达式是会异常的,但是这句测试的代码则是通过的。
  b.
  XCTAssertThrowsSpecific(expression,exception_class,...):表达式抛出异常,并且抛出的异常类属于NSException,才会执行通过;反之。
  e.g.
  XCTAssertThrowsSpecific([modelonlyTest02],NSException,@"wgj001");--onlyTest02方法实现时:运行崩溃;onlyTest02方法未实现时,执行未实现的方法,系统会自动生成NSException类型的异常,符合定义的NSException类,测试代码运行通过。
  c.
  XCTAssertThrowsSpecificNamed(expression,exception_class,exception_name,...):表达式抛出异常,并且抛出的异常类属于NSException,并且异常类的名字符合定义的名字时,才会执行通过;反之。
  e.g.
  XCTAssertThrowsSpecificNamed([modelonlyExceptionTest],NSException,@"自定义异常",@"wgj002");
  model中的实现方法:
  @throwexx;
  此种,测试代码是通过的。
  若改为:
  XCTAssertThrowsSpecificNamed([modelonlyExceptionTest],NSException,@"随便写的名字",@"wgj002");则测试代码不通过,因为异常名字不匹配。