测试在项目开发中是至关重要的一环,大公司一般会有测试小组,专门进行各种测试;一些小的公司可能没有测试组,这时程序猿自身测试就显得尤为重要了,这里就讲下单元测试即 Unit Tests。
1.什么是软件测试、单元测试
具体概念这里可以到维基百科英文版
2.一般在创建项目时会勾选 Include Unit Tests
点击UnitTestTests.m
,可看到测试相应的方法
- (void)setUp {
[super setUp];
// Put setup code here. This method is called before the invocation of each test method in the class.
// 1.重置对象,为测试条件做准备
}
// 每次测试方法执行的时候都会跑
- (void)tearDown {
// Put teardown code here. This method is called after the invocation of each test method in the class.
// 2.置空
[super tearDown];
}
// 测试代码
- (void)testExample {
}
查看详细的每个测试方法测试情况在这里方便查看
3.举个单元测试的例子
我们在viewController.m
里面创建一个方法,就是简单的两个数相加
- (int)add:(int)numberA with:(int)numberB
{
return numberA + numberB;
}
注意:这里需要在viewController.h
声明一下这个方法,因为在测试的时候要导入viewController.m
头文件,才能调用并测试里面的方法。
- (int)add:(int)numberA with:(int)numberB;
现在我们到UnitTestTests
去测试这个方法
// 1. Given:初始条件设置
int num1 = 1;
int num2 = 2;
// 2. When:被测试的一些方法
int result = [self.vc add:num1 with:num2];
// 3. Then:测试判断结果
XCTAssertEqual(result, 3);
注意:这里要使用断言来判断结果是否正确,不然这个测试就没有意义了,因为你也不知道测试的结果是否正确。断言在XCTestAssertions.h
里面有,介绍的很详细。
下面再测试一个超时功能,在viewController
类里,同上:
- (void)sendRequest:(void(^)(NSString *targetString))finished
{
dispatch_queue_t globle = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(globle, ^{
[NSThread sleepForTimeInterval:3];
dispatch_async(dispatch_get_main_queue(), ^{
finished(@"完成");
});
});
}
- (void)testTimeOut {
XCTestExpectation *expectation = [self expectationWithDescription:@"Async test was failed"];
}
[self.vc sendRequest:^(NSString *targetString) {
// 1.传回来的的值是否正确,是否存在
XCTAssertNotNil(targetString);
// 2.是否按时传回(履行,执行)
[expectation fulfill];
}];
// 如果走了 [expectation fulfill] 方法就不会再走下面的方法了,说明已经按时返回了。
// 我们可以看到如果这个时间小于3秒的话,就会报错
[self waitForExpectationsWithTimeout:5 handler:^(NSError * _Nullable error) {
NSLog(@"%@",error);
}];
注意:写测试方法时,只要在方法名前缀test就可以,Xcode会识别这个方法是测试方法。
4.性能测试
同样在UnitTestTests
里面,你还会看到这个方法,这里就是代码性能测试的地方。
- (void)testPerformanceExample {
[self measureBlock:^{
// Put the code you want to measure the time of here.
// code
}];
}
// 性能测试提高精度,只测试一部分代码
- (void)testUseFileHandlePerformance
{
[self measureMetrics:@[XCTPerformanceMetric_WallClockTime] automaticallyStartMeasuring:NO forBlock:^{
// 只测试一部分功能代码
[self startMeasuring];
// code
[self stopMeasuring];
}];
}
查看性能测试结果:
我们看到代码执行 ,Metric
:时间作为性能的指标; Average
:表示平均时间;Baseline
:表示你设置一个基线;Result
:是指平均时间和你是设置的基线进行比较后得出的结果,百分比表示的;max STDDEV
:表示标准偏差 10%。
我们做单元测试,不要把测试方法写的很复杂,也不要把一个庞大的功能一下子拿过来测试,最好是分成如干个小功能进行测试,不然单元测试就变得复杂了,很多人就是因此放弃写单元测试,其实单元测试是很有用的。
Demo下载地址 https://github.com/MichaelSSY/UITest-UnitTest