这里主要详细的说明补充一下上篇文章:
首先单元测试:
在Xcode中如下:
第一步、新建工程,勾选Include Unit Tests,如下图:
第二步、点击下一步,创建工程之后,你会发现多出一个ProjectNameTests的文件夹,如下图:
image.png
如果在创建项目时没有勾选这一项,也可以通过下面的方式来创建,如下图: image.png
image.png
image.png
第三步、UnitTestDemoTests.m的说明和使用
1、UnitTestDemoTests.m的说明:
/*
*用于在测试前设置好要测试的方法,在测试方法调用之前调用,如,初始化的代码
*/
- (void)setUp {
[super setUp];
// Put setup code here. This method is called before the invocation of each test method in the class.
}
/*
*用于在测试后将设置好的要测试的方法拆卸掉,释放资源
*/
- (void)tearDown {
// Put teardown code here. This method is called after the invocation of each test method in the class.
[super tearDown];
}
/*
*测试示例,一定要以test开头
*比如,你可以创建, - (void)testMyProject{}
*/
- (void)testExample {
// This is an example of a functional test case.
// Use XCTAssert and related functions to verify your tests produce the correct results.
}
/*
*性能测试示例
*/
- (void)testPerformanceExample {
// This is an example of a performance test case.
[self measureBlock:^{
// Put the code you want to measure the time of here.
//在这里存放需要测试性能的代码
}];
}
2、使用
在ViewController中声明一个函数并实现,如,
- (BOOL)getMyBoolValue;
...
...
- (BOOL)getMyBoolValue
{
return YES;
}
在UnitTestDemoTests.m中导入ViewController的头文件,声明一个ViewController的对象并在setUp方法中初始化。如下,
#import <XCTest/XCTest.h>
#import "ViewController.h"
@interface UnitTestDemoTests : XCTestCase
@property (nonatomic,strong) ViewController *viewController;
@end
@implementation UnitTestDemoTests
/*
*用于在测试前设置好要测试的方法,在测试方法调用之前调用,如,初始化的代码
*/
- (void)setUp {
[super setUp];
self.viewController = [[ViewController alloc]init];//初始化
}
/*
*用于在测试后将设置好的要测试的方法拆卸掉,释放资源
*/
- (void)tearDown {
self.viewController = nil;//释放
[super tearDown];
}
/*
*测试示例,一定要以test开头
*比如,你可以创建, - (void)testMyProject{}
*/
- (void)testMyBoolFunc
{
BOOL result = [self.viewController getMyBoolValue];
XCTAssertEqual(result, NO,@"测试没通过");
}
接着,Command+U进行测试,然而,控制台可能会输出类似下面的错误提示:
Connection peer refused channel request forr"dtxproxy:XCTestDriverInterface:XCTestManager_IDEInterface"; channel canceled Failed to run tests: The operation couldn’t be completed. (DTXProxyChannel error 1.)
这时候,就要先Command + R运行一下项目,然后再Command+U进行测试。
当然,上面的例子没有测试通过,如下
控制台输出:
image.png
把XCTAssertEqual(result, NO,@"测试没通过");中NO修改为YES,测试通过,如下:
image.png
控制台输出:
image.png
3、testPerformanceExample性能测试示例的使用和解释
如下,写一个for循环并输出值,然后Command+U进行测试,
image.png图中的0.145 sec只是CPU运算的时间,时间显示和输出的时间可能比这个值要大一些
4、最后介绍一下XCTAssertEqual以及相关的宏定义函数。
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没有发生具体异常、具体异常名称的异常时通过测试,反之不通过
特别注意下XCTAssertEqualObjects和XCTAssertEqual。
XCTAssertEqualObjects(a1, a2, format...)的判断条件是[a1 isEqual:a2]是否返回一个YES。
XCTAssertEqual(a1, a2, format...)的判断条件是a1 == a2是否返回一个YES。
UI测试
在写好ui测试的用例之后,如果碰到不会写的用例,就把鼠标的光标放到某一个空白位置,然后在点击Xcode上的这个红点,:
点击按钮.png
光标放在这里之后.png
你就会看见出来一个灰色的三角形一样的东西(204行),然后你可以一步步点击你的软件,点击一步,这个三角形这里会生成一段你点击的UI测试代码,然后,把上面显示的一些错误的部分,换成自己的就好了,这样子,你点击你的软件一步,Xcode就会自动生成测试代码,下次直接运行这些代码就好了。
最后说一下,测试覆盖率的问题:
首先,要在测试的过程看到每个方法的覆盖率大小,要先在Xcode进行设置一下:
Code Coverage的基本设置图如下,更改Scheme的Test中的勾选项,把 Gather coverage data 勾上,然后就可以Command+U或者指定某个UI自动化用例执行了。另外,在Scheme的编辑中,可以指定Test时需要测试哪些单元测试,具体见图:
image.png
接入APP是不能直接访问静态库工程的文件的,因此接入APP的UI测试得不到静态库工程的代码覆盖率,如何解决呢?很简单,虽然静态包不能单独运行UI,但可以在静态库的Scheme-Test中添加接入APP的测试Target,就可以在静态库的project里用看到UI Testing的用例并执行。测试类也可以直接访问到静态库工程中的文件,并得到代码覆盖率结果了。同样,这里也需要勾选上 Gather coverage data, 如下图:
image.png
再看我们得到的代码覆盖率结果,鼠标悬浮在蓝条时会有数值,点击箭头能进到文件看方法的执行次数。如图:
image.png
结果是得到了,但每次都要悬浮到蓝条上看数值,以及得不到整体统计,可读性非常差。
如何使代码覆盖率测试结果增强可读性?
测试结果文件的位置,从工程目录的生成app,打开finder,往上找Intermediates文件夹就行了。Coverage.profdata就是我们要找的结果文件。
image.png
image.png
XCode代码测试结果使用了LLVM Code Coverage Mapping Format, 具体格式介绍参考http://llvm.org/docs/CoverageMappingFormat.html。只要是标准格式,就可以按想要的方式解读。这时llvm-cov上场了,llvm是随Xcode一起安装的,不需要另外安装。如果遇到解析文件报错LLVM版本不对的,可以用Xcode-select --print-path看下生成文件时的Xcode路径和跑用例时用的Xcode是不是一个,如果不是,重新选择。
解析文件的命令为xxx/llvm-conv report -instr-profile xxx/Coverage.profdata xxx/xx.app/xx,其中report为参数,可以换成show得到各文件结果。xx.app要取与Coverage.profdata同目录的Products文件夹内的。
image.png
这时,我们可以直观的得到各个文件的代码覆盖率数值信息,这里带入了杂质信息,真机和模拟器均存在。但是,这是无关紧要的。我们APP开发或SDK开发都会习惯添加类前缀,那么通过使用shell脚本筛选我们需要的行,重新计算统计值,就能得到app部分文件或静态库文件的统计结果。
网友评论