iOS 单元测试
单元测试
Xcode 的单元测试分为:
- 逻辑测试
逻辑测试比较简单,主要是运用断言对函数执行结果作测试判断。 - 性能测试
性能测试常被功能更强大的 Instruments 替代。 - 异步函数测试
通常代码中会有大量的异步执行方法,并且这些方法往往都比较重要。
下文会简单介使用 XCTestExpectation 对异步函数做单元测试。
注意点:
- 所有的测试类都应该继承于:XCTestCase
- 所有的测试方法的命名都必须以 test 开头否则 Xcode 无法识别
- 所有的测试方法不能有返回值
常用单元测试断言
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没有发生具体异常、具体异常名称的异常时通过测试,反之不通过
异步测试: XCTestExpectation
开源项目 AFNetworking 提供了很详细的单元测试类:
AFHTTPSessionManagerTests.m 中包含了大量的异步测试方法,我们解读一个:
//异步文件下载
- (void)testDownloadFileCompletionSpecifiesURLInCompletionWithManagerDidFinishBlock {
__block BOOL managerDownloadFinishedBlockExecuted = NO;
__block BOOL completionBlockExecuted = NO;
__block NSURL *downloadFilePath = nil;
//初始化 XCTestExpectation 实例
XCTestExpectation *expectation = [self expectationWithDescription:@"Request should succeed"];
// self.manager -> AFHTTPSessionManager *manager;
// 设置文件存储路径
[self.manager setDownloadTaskDidFinishDownloadingBlock:^NSURL *(NSURLSession *session, NSURLSessionDownloadTask *downloadTask, NSURL *location) {
managerDownloadFinishedBlockExecuted = YES;
NSURL *dirURL = [[[NSFileManager defaultManager] URLsForDirectory:NSLibraryDirectory inDomains:NSUserDomainMask] lastObject];
return [dirURL URLByAppendingPathComponent:@"t1.file"];
}];
NSURLSessionDownloadTask *downloadTask;
//任务加载
downloadTask = [self.manager
downloadTaskWithRequest:[NSURLRequest requestWithURL:self.baseURL]
progress:nil
destination:nil
completionHandler:^(NSURLResponse *response, NSURL *filePath, NSError *error) {
downloadFilePath = filePath;
completionBlockExecuted = YES;
//fulfilled
[expectation fulfill];
}];
[downloadTask resume];
//异步超时设定
[self waitForExpectationsWithTimeout:10.0 handler:nil];
//执行结果判定
XCTAssertTrue(completionBlockExecuted);
XCTAssertTrue(managerDownloadFinishedBlockExecuted);
XCTAssertNotNil(downloadFilePath);
}