写在前面
- 当一个项目中拥有的单元测试很客观,在对代码后期修改时,就可以很容易的知道是否破坏了老的业务逻辑,大大降低了回归错误的可能。
- 对于单元测试,它可以更好的描述代码的行为,写单元测试时,基本上思考的角度是假定某个方法,在某个特定的环境中,能够有预期的表现。
- 要做到真正的单元测试,你需要保证你每个测试用例所针对的仅仅是一个基本单元,而不是一个有很多复杂依赖的综合行为。
- 关于行为测试:在面向对象的程序设计中,一般最基本的单元就是一个类的方法,所以在单元测试中,就是要针对这些方法编写合适的测试用例。
工具
XCTest是苹果在 iOS7 和Xcode 5引入的一个简单而强大的测试框架。
XCode中的添加方法
方法1: 在创建项目的时候,勾选Include UI Tests
方法2: 创建项目的时候没有勾选Include UI Tests,莫着急,可以
选择File->New->Target->iOS Unit Testing Bundle进行添加
断言
使用断言来输出测试的结果,举三个例子:
- XCTAssertNotNil(a1, format…)
不为空判断,a1不为空时通过,反之不通过
XCTAssertNotNil(@"not nil string", @"string can not be nil");
- XCTAssertTrue(expression, format...)
当expression求值为TRUE时通过,反之不通过
XCTAssertTrue(1, @"Can not be zero");
- XCTAssertNotEqual(a1, a2, format...)
当a1和a2不相等则通过,反之不通过
XCTAssertNotEqual(generString, @"", @"output cant be empty");
写一个测试用例
测试用例的三步曲: 排列资源、执行行为、断言结果,参考了很多开源项目,一般习惯用Arrange、Act、Assert或是Given,When,Then来表示。所以在公司开源的SDK上写了一些单元测试,如下:
针对加密类的一个测试用例
行为测试:inputString传入后是否能获取outputString。
/// input is string , output is string
- (void)test_setInput_string_for_output_string {
/// Given
NSString *infoString = [MerculetEncrypteInfo info];
/// When
NSString *generString = [MerculetEncrypteHelper generateString:infoString];
/// Then
XCTAssertNotEqual(generString, @"", @"output cant be empty");
}
针对网络请求类的一个测试用例
行为测试:测试MWURLRequestManager的get请求成功与否。
- (void)testSetStartURLRequestManagerRequest {
// Given
MWURLRequestManager *manager = [[MWURLRequestManager alloc] init];
NSString *urlString = @"https://httpbin.org/get";/// get请求
XCTestExpectation *expextation = [self expectationWithDescription:urlString];
// When
[manager GET:urlString
headers:nil
success:^(NSURLResponse *response, id responseObject, NSData *data) {
self.response = (NSHTTPURLResponse *)response;
[expextation fulfill];
} failure:^(NSURLResponse *response, NSError *error) {
self.response = (NSHTTPURLResponse *)response;
[expextation fulfill];
}];
[self waitForExpectationsWithTimeout:30 handler:^(NSError * _Nullable error) {
// 等待30秒,若该测试未结束(未收到 fulfill方法)则测试结果为失败
}];
// Then
// XCTAssertNotNil(response, "response should not be nil");
XCTAssertTrue(self.response.statusCode == 200, "response status code should be 200");
}
网友评论