最简单的单元测试
1.新建项目:
2.最简单的测试,注意截图路径的问题
进入到这个类,setUp是每个测试方法调用前执行,tearDown是每个测试方法调用后执行。testExample是测试方法,和我们新建的没有差别。不过测试方法必须testXXX的格式,且不能有参数,不然不会识别为测试方法。测试方法的执行顺序是字典序排序。
按快捷键Command + U进行单元测试,这个快捷键是全部测试。
testExample方法中输入
NSLog(@"自定义测试testExample");
int a= 3;
XCTAssertTrue(a == 0,"a 不能等于 0");
点击播放按钮,开始单个方法的测试:
出现如下结果,由于我们断言a是等于0的,而a等于3,所以测试没有通过。当然有其它的,用到再看,demo里都有。
进行网络请求的测试
使用CocoaPods安装AFNetworking和STAlertView(CocoaPods安装和使用教程 )
Pofile:
platform :ios, '7.0'
target 'UnitTestDemoTests' do
pod 'AFNetworking', '~> 2.5.0'
pod 'STAlertView', '~> 1.0.0'
end
target 'UnitTestDemoTestsTests' do
pod 'AFNetworking', '~> 2.5.0'
pod 'STAlertView', '~> 1.0.0'
end
iOS9的http安全问题:现在进行异步请求的网络测试,由于测试方法主线程执行完就会结束,所以需要设置一下,否则没法查看异步返回结果。在方法结束前设置等待,调回回来的时候再让它继续执行。(另一种异步函数的单元测试)定义宏如下:
//waitForExpectationsWithTimeout是等待时间,超过了就不再等待往下执行。
#define WAIT do {\
[self expectationForNotification:@"RSBaseTest" object:nil handler:nil];\
[self waitForExpectationsWithTimeout:30 handler:nil];\
} while (0);
#define NOTIFY \
[[NSNotificationCenter defaultCenter]postNotificationName:@"RSBaseTest" object:nil];
增加测试方法testRequest:
-(void)testRequest{
// 1.获得请求管理者
AFHTTPRequestOperationManager *mgr = [AFHTTPRequestOperationManager manager];
mgr.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"text/html",nil];
// 2.发送GET请求
[mgr GET:@"http://www.weather.com.cn/adat/sk/101110101.html" parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(@"responseObject:%@",responseObject);
XCTAssertNotNil(responseObject, @"返回出错");
NOTIFY //继续执行
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"error:%@",error);
XCTAssertNil(error, @"请求出错");
NOTIFY //继续执行
}];
WAIT //暂停
}
有时候我们想测试一下整个流程是否可以跑通,比如获取验证码、登录、上传头像,查询个人资料。其实只要输入验证码就可以完成整个测试。这时候就需要用到输入框了,以便程序继续执行。使用了一个第三方的弹出输入框STAlertView,前面已经设置。
STAlertView的使用方法:
self.stAlertView = [[STAlertView alloc]initWithTitle:@"验证码" message:nil textFieldHint:@"请输入手机验证码" textFieldValue:nil cancelButtonTitle:@"取消" otherButtonTitle:@"确定" cancelButtonBlock:^{
//点击取消返回后执行
[self testAlertViewCancel];
NOTIFY //继续执行
} otherButtonBlock:^(NSString *b) {
//点击确定后执行
[self alertViewComfirm:b];
NOTIFY //继续执行
}];
[self.stAlertView show];
3.性能测试
性能测试主要使用 measureBlock 方法 ,用于测试一组方法的执行时间,通过设置baseline(基准)和stddev(标准偏差)来判断方法是否能通过性能测试。
- (void)testPerformanceExample {
// This is an example of a performance test case.
[self measureBlock:^{
//Put the code you want to measure the time of here.
//你的性能测试的代码放在这里
}];
}
4.命令行测试
测试不仅可以在xcode中执行,也可以在命令行中执行,这个便于代码持续集成和构建,在git提交中也编译检查代码
如果你有development-enabled设备插入,你可以按照名称或 id 调用他们。例如,如果你有一个名为”Development iPod touch”的 iPod 设备连接了测试的代码,可以使用下面的命令来测试代码
> xcodebuild test -project MyAppProject.xcodeproj -scheme MyApp -destination 'platform=iOS,name=Development iPod touch
测试也可以在 iOS模拟器上运行。使用模拟器可以应对不同的外形因素和操作系统版本。例如
> xcodebuild test -project MyAppProject.xcodeproj -scheme MyApp -destination 'platform=iOS Simulator,name=iPhone,0S=7.0'
-destination 参数可以被连接在一起,这样你只需使用一个命令,就可以跨目标进行指定集成共享方案。例如,下面的命令把之前的三个例子合并到一个命令中
> xcodebuild test -project MyAppProject.xcodeproj -scheme MyApp
-destination 'platform=OS X,arch=x86_64'
-destination 'platform=iOS,name=Development iPod touch'
-destination 'platform=iOS Simulator,name=iPhone,0S=7.0'
断言种类:
//通用断言
XCTAssert(expression, format...)
//常用断言:
XCTAssertTrue(expression, format...)
XCTAssertFalse(expression, format...)
XCTAssertEqual(expression1, expression2, format...)
XCTAssertNotEqual(expression1, expression2, format...)
XCTAssertEqualWithAccuracy(expression1, expression2, accuracy, format...)
XCTAssertNotEqualWithAccuracy(expression1, expression2, accuracy, format...)
XCTAssertNil(expression, format...)
XCTAssertNotNil(expression, format...)
XCTFail(format...) //直接Fail的断言
注意点
都是血与泪的教训
使用pod的项目中,在XC测试框架中测试内容包括第三方包时,需要手动去设置Header Search Paths才能找到头文件 ,还需要设置test target的PODS_ROOT.
Enable Testability 设置为YES
xcode7要使用真机做跑测试时,证书必须配对,否则会报错exc_breakpoint错误