缘由:过去一直认为测试单元或者断言这玩意用不到,但是当我们的测试走了,我们才安静的发现不能没有他,然后老大把测试的任务交给了我,建议我去写个测试用例检测一下UI交互,以及网络接口返回数据是否符合预期,最后发现轻量级的还是比较建议使用UITestCase,虽然只能测试一下纯业务逻辑和网络接口,也很开心了,毕竟后台给了40个新的接口,没人测试,我只能用这个,保证返回数据的准确性。
什么是单元测试?
苹果嫡系产物,直接在app的项目名+ Tests
的测试模块(每个项目都会有)中测试业务逻辑,集中化管理测试用例,将测试的对象设置成最小的单元,方便开发人员测试
使用场景
测试一些纯业务逻辑的东西,还有就是网络接口返回的数据是否符合预期的判断
优点
统一化管理,书写代码,可以多次的进行回归测试,方便修改,节约成本和时间,一劳永逸
缺点
是不能和UI交互,太过于复杂的业务逻辑没法测试。
测试函数的要求是:1.必须无返回值;2.以test开头;
Command + U
去执行测试用例
说说系统中自带的方法
1.
setUp
所有的test,不论运行一个,还是运行很多个,都会调用,作用了viewDidLoad
差不多,生成公用属性都可以用这个
2.tearDown
结束的时候调用这个
3.[self measureBlock:^{ NSLog(@"我是测试看看是不是10变"); }]
不论在什么方法中调用,这个方法是调用10次,主要是因为一次不一定准(我猜的)。
2016-08-07 17:00:58.165 LGWaterMark[1893:77035] 我是测试看看是不是10变
2016-08-07 17:00:58.165 LGWaterMark[1893:77035] 我是测试看看是不是10变
2016-08-07 17:00:58.166 LGWaterMark[1893:77035] 我是测试看看是不是10变
2016-08-07 17:00:58.166 LGWaterMark[1893:77035] 我是测试看看是不是10变
2016-08-07 17:00:58.166 LGWaterMark[1893:77035] 我是测试看看是不是10变
2016-08-07 17:00:58.166 LGWaterMark[1893:77035] 我是测试看看是不是10变
2016-08-07 17:00:58.167 LGWaterMark[1893:77035] 我是测试看看是不是10变
2016-08-07 17:00:58.167 LGWaterMark[1893:77035] 我是测试看看是不是10变
2016-08-07 17:00:58.167 LGWaterMark[1893:77035] 我是测试看看是不是10变
2016-08-07 17:00:58.167 LGWaterMark[1893:77035] 我是测试看看是不是10变
** 下面说说具体的语法 **
一. XCTFail
XCTFail是一个宏,其作用就是让测试失败
后面的就是要报告的错误信息,由我们自定。
打印是这样的,显示了第几行,那个文件,哪个方法~
可以在发送网络请求的时候,如果是error的情况下,直接使用这个方法,打印具体的数据,快速定位。
Test Case '-[GEDemoTestCase testFail]' started.
/Users/wangxin/Get_iOS1.0/GetTests/GEDemoTestCase.m:27: error: -[GEDemoTestCase testFail] : failed - No implementation for "-[GEDemoTestCase testFail]"
二.其他各种测试
二、各种断言测试: (网络摘抄)
XCTFail(format…) 生成一个失败的测试;
XCTAssertNil(a1, format...)为空判断,a1为空时通过,反之不通过;
XCTAssertNotNil(a1, format…)不为空判断,a1不为空时通过,反之不通过;
XCTAssert(expression, format...)当expression求值为TRUE时通过;
XCTAssertTrue(expression, format...)当expression求值为TRUE时通过;
XCTAssertFalse(expression, format...)当expression求值为False时通过;
XCTAssertEqualObjects(a1, a2, format...)判断相等,[a1 isEqual:a2]值为TRUE时通过,其中一个不为空时,不通过;
XCTAssertNotEqualObjects(a1, a2, format...)判断不等,[a1 isEqual:a2]值为False时通过,
XCTAssertEqual(a1, a2, format...)判断相等(当a1和a2是 C语言标量、结构体或联合体时使用,实际测试发现NSString也可以);
XCTAssertNotEqual(a1, a2, format...)判断不等(当a1和a2是 C语言标量、结构体或联合体时使用);
XCTAssertEqualWithAccuracy(a1, a2, accuracy, format...)判断相等,(double或float类型)提供一个误差范围,当在误差范围(+/-accuracy)以内相等时通过测试;
XCTAssertNotEqualWithAccuracy(a1, a2, accuracy, format...) 判断不等,(double或float类型)提供一个误差范围,当在误差范围以内不等时通过测试;
XCTAssertThrows(expression, format...)异常测试,当expression发生异常时通过;反之不通过;(很变态)
XCTAssertThrowsSpecific(expression, specificException, format...) 异常测试,当expression发生specificException异常时通过;反之发生其他异常或不发生异常均不通过;
XCTAssertThrowsSpecificNamed(expression, specificException, exception_name, format...)异常测试,当expression发生具体异常、具体异常名称的异常时通过测试,反之不通过;
XCTAssertNoThrow(expression, format…)异常测试,当expression没有发生异常时通过测试;
XCTAssertNoThrowSpecific(expression, specificException, format...)异常测试,当expression没有发生具体异常、具体异常名称的异常时通过测试,反之不通过;
XCTAssertNoThrowSpecificNamed(expression, specificException, exception_name, format...)异常测试,当expression没有发生具体异常、具体异常名称的异常时通过测试,反之不通过
PS:
XCTAssertEqual(a1, a2, format...)
这个是(1 == 3)基本数据类型,XCTAssertEqualObjects(a1, a2, format...)判断相等
是对象类型,大多数测试都是好使的。
在TestCase中可以写逻辑判断,也可以去写一下网络请求数据的判断,但是问题是网络是异步的,那么就要去保存TestCase的生命,只有当数据加载完了,判断完了在让他死。github早在3年前就写好了分类~
github大神的分类
1.在你的testCase中#import "XCTest+Async.h"
就好了
2.在项目中直接使用
判断网络返回数据的正确性
- (void)testExample {
ASYNC_TEST_START
[[AFHTTPSessionManager manager] GET:@"http://api.test.wangqiujia.com.cn/chaos/v2/dynamic/recommended" parameters:nil success:^(NSURLSessionDataTask *task, id responseObject) {
NSInteger stuateCode = [responseObject[@"statusCode"] integerValue];
if (stuateCode == 200 || stuateCode == 0) {
//获取sorts字典
NSArray *sorts = responseObject[@"sorts"];
//获取的字典
NSDictionary *items = responseObject[@"items"];
NSMutableArray *models = [NSMutableArray array];
NSArray *tempArr = nil;
for(NSString *type in sorts){
if ([type isEqualToString:@"activity"]) {
tempArr = [ActiviteModel objectArrayWithKeyValuesArray:items[type]];
}else if([type isEqualToString:@"course"]){
tempArr = [CourseModel objectArrayWithKeyValuesArray:items[type]];
}else if([type isEqualToString:@"league"]){
tempArr = [THMatchModel objectArrayWithKeyValuesArray:items[type]];
}
if (tempArr.count) {
[models addObject:tempArr];
}
}
//进行对模型中的数据进行检查
ActiviteModel *am = tempArr[0];
//title 不能为空
XCTAssertNotNil(am.title);
//uid 是NSString类型
XCTAssertTrue([am.uid isKindOfClass:[NSString class]]);
//city_code == nil
XCTAssertNil(am.city_code);
//start_unixstamp 长度一定不是0
XCTAssert(am.start_unixstamp.length != 0);
}
ASYNC_TEST_DONE
} failure:^(NSURLSessionDataTask *task, NSError *error) {
XCTFail("出现error");
ASYNC_TEST_DONE
}];
ASYNC_TEST_END
}
1.代码解析,在开始网络请求的时候,先去使用
ASYNC_TEST_START
保命,然后请求网络,成功或者失败都要ASYNC_TEST_DONE
完成任务,如果失败,可以强制奔溃,打印原因,到了最后记得ASYNC_TEST_END
不要命就好了~
2.先字典转模型,然后那对象中的属性进行逻辑的判断,非常方便,多次使用,一劳永逸
3.公司的多个接口都要去测试,那么我们可以全都写测试用例,到时候屏幕全绿,全都正确,爽死了