xcode进行代码覆盖率测试
去年写的文章,搬到cnblog
本文所述的方法只对xcode5做过测试,xcode6是否可行尚未可知。
配置编译选项
首先请参考苹果官方的文档Configuring Xcode for Code Coverage进行相依的编译选项配置,以生成最基所需的基础数据。为了区别与Release&Debug的版本,建议新建一个叫做Coverage(任何名字都行)编译配置Configuration(从Debug Copy),方法在上面的文档里面有说明。
对这个Coverage编译选项,做如下配置:(仅对Coverage做修改,不要影响到原来的Debug,Release以及Distribution
Generate Debug Symbols配置成YES
Generate Test Coverage Files配置成YES
Instrument Program Flow配置成YES做了上面的配置以后,如果为模拟器编译Coverage版本,那么可以看到~/Library/Developer/Xcode/DerivedData/{project_dir}/Build/Intermediates/{target_name}.build/Coverage-iphonesimulator/{target-name}.build/Objects-normal/i386下面,有一些.gcno文件。
收集运行时数据
程序运行的时候,会自动记录覆盖率相关的数据,但是这个数据只有在程序正常退出的时候才会写到文件。对于OS X程序来说,只要通过Quit菜单退出即可;
对与ios程序来说,要想正常的退出app,只有将info.plist里面的UIApplicationExitsOnSuspend置为YES,这样按home键就退出了,但这种方法需要干扰正常的应用逻辑,不利于维护;
第二种方式是通过添加代码,只要在AppDelegate里面添加这样的代码即可:
- (void)applicationDidEnterBackground:(UIApplication *)application
{
#if NT_COVERAGE
extern void __gcov_flush(void);
__gcov_flush();
#endif
}
NT_COVERAGE是一个自定义的宏,建议在主taget的Build Setting/Preprocessor Macros为Coverage配置添加一个宏`NT_COVERAGE=1`,这样通过这个宏可以用来过滤这些专门为覆盖率测试所写的代码片段。
以模拟器为例,将app运行起来,进行一些操作,最后切换到后台,此时~/Library/Developer/Xcode/DerivedData/{project_dir}/Build/Intermediates/{target_name}.build/Coverage-iphonesimulator/{target-name}.build/Objects-normal/i386下应该有一些.gcda文件。
转换数据
这一步是将收集的数据转换成可读的形式,使用一个开源库XcodeCoverage可以完美做到这一点:得到一组html文件,可以方便地产看每个目录下的每个类,每个函数的执行情况。
请按照这个链接所指向的文章的指示进行配置。
这个开源库就是一些脚本及几个很小的可执行文件,建议直接放在project的目录下即可。脚本下面的getcov是个bash脚本,可以进行一些必要的修改:
1)、exclude_data函数里面,可以排除一些不想统计覆盖率的代码
假设一些第三方库都位于library子目录,可以这样来排除
LCOV --remove ${LCOV_INFO} "library/*" -d "${OBJ_DIR}" -o ${LCOV_INFO}2)、generate_report函数里面,可以更改产生html的目录
我是这么改的,在文件的头部增加 REPORT_DIR=${DIR}/report,指定html的目录为XcodeCoverage/report
generage_report被改成:
generate_report()
{
"${LCOV_PATH}/genhtml" --output-directory “${REPORT_DIR}” ${LCOV_INFO}
cd ${REPORT_DIR}
open index.html
}
当完成数据收集后,运行./getcov命令即可。
- 如何针对ios设备进行覆盖率测试
与模拟器相比,区别的地方在于测试数据输出的位置,因为默认的位置在设备上是不可写的,因此需要在appDelegate里面做一些修改:
- (void)applicationDidEnterBackground:(UIApplication *)application
{
#if NT_COVERAGE
#if !TARGET_IPHONE_SIMULATOR
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
setenv("GCOV_PREFIX", [documentsDirectory cStringUsingEncoding:NSUTF8StringEncoding], 1);
setenv("GCOV_PREFIX_STRIP", "13", 1);
#endif
extern void __gcov_flush(void);
__gcov_flush();
#endif
}
第一个setenv的意思是将数据的根目录设置为app的Documents;
第二个setenv的意思是strip掉一些目录层次,因为覆盖率数据默认会写入一个很深的目录层次。
在完成app测试之后,将这些.gcda文件拷贝到对应.gcno文件同样的目录,在我的测试case下是~/Library/Developer/Xcode/DerivedData/{project_dir}/Build/Intermediates/{target_name}.build/Coverage-iphoneos/{target-name}.build/Objects-normal/armv7。然后运行上面3中getcov命令即可。
与单元测试相结合
XcodeCoverage介绍了如何在单元测试后自动生成覆盖率测试报告,只是一个脚本配置而已。
需要注意的是,如果使用单元测试,那么单元测试target也必须使用上文所说的Coverage编译配置项,因为运行单元测试时,会自动编译主target的同名编译配置项。这个开源工具是通过run_code_coverage_post.sh来在test执行完毕之后来启动覆盖率数据收集的,我修改了一下这个脚本,打开一个终端窗口来打印执行过程:
#!/bin/bash
button=`/usr/bin/osascript <<EOT
tell application "Finder"
activate
set dialogText to "Generate code coverage report?"
set cancelText to "Cancel"
set okText to "OK"
set myReply to button returned of (display dialog dialogText buttons
{cancelText, okText} cancel button cancelText default button okText)
end tell
EOT`
if [[ $button = "OK" ]]; then
`/usr/bin/osascript <<EOT
tell application "Terminal"
close back window
do script "/bin/bash ${SRCROOT}/XcodeCoverage/getcov"
end tell
EOT`
fi
echo "Done.”
代码覆盖率的结果,可以用来指导开发者进行充分的调试,或是评估单元测试的case是否足够;第一次完成上面的配置之后,以后的使用是很方便的。
另外需要指出的几点:
1)__gcov_flush在一次测试中是可以被反复调用的,可以边测试边看覆盖率;
2)本文对XcodeCoverage所做的几处修改,在这里可以找到;
3)另外每次覆盖率测试最好用一个全新的build,因此需要将上次build的中间文件全部删除,可以打开Xcode的Product菜单,按住Option键,点击Clear Build Folder…。
xcode进行代码覆盖率测试的更多相关文章
- iOS代码覆盖率测试工具
基于lcov-1.11的:CodeCoverage4iOS 阅读目录 环境准备 Xcode工程配置 构建并安装程序 收集代码覆盖率 过滤结果 合并多个Coverage.info⽂件⽣成覆盖率报告: ...
- Xcode真机测试could not find developer disk image解决方法
原文地址:http://my.oschina.net/u/2340880/blog/521700 Xcode真机测试could not find developer disk image解决方法 在使 ...
- WWDC15 Session笔记 - Xcode 7 UI 测试初窥
https://onevcat.com/2015/09/ui-testing/ WWDC15 Session笔记 - Xcode 7 UI 测试初窥 Unit Test 在 iOS 开发中已经有足够多 ...
- Xcode 真机测试破解方法(转加修改)xcode 4.3 通过
Xcode 真机测试破解方法(转加修改)xcode 4.3 通过 生成本机证书 应用程序->实用工具->钥匙串访问 菜单:钥匙串访问->证书助理->创建证书, 然后按以下图片顺 ...
- VS2015+NUnit+OpenCover 完成单元测试代码覆盖率测试
1.VS2015+NUnit+OpenCover 完成单元测试代码覆盖率测试 https://download.csdn.net/download/qq_39441918/10522539 2.*注意 ...
- Spring Boot 代码覆盖率测试
代码覆盖率测试是规范软件开发流程里一个必不可少的环节.一般都是在PG末尾阶段,伴随着IT自测产生. ↑以上,是自己yy出来的啊,反正我司是这样要求的.不跑覆盖率,鬼知道你在代码里夹杂了一些什么东西. ...
- 使用Cobertura做代码覆盖率测试
经验总结:首先要把cobertura.jar包含ant的classpath路径中,其次要求它包含在测试用例的classpath中: 使用cobertura做代码覆盖率测试中出现的问题:覆盖率始终为0, ...
- 解决Xcode真机测试时ineligible devices的问题
升级了Xcode到6.3,连接真机测试时,出现不能选择设备.如图: 设备系统版本是8.3的,Xcode连接其他低系统版本的设备做真机测试时就不会有这个问题. 有人说这是Xcode6.3的bug. 我的 ...
- Xcode真机测试could not find developer disk image解决方法(支持iOS9.2)
这个问题开发者经常碰到,因为当我们更新手机iOS版本的时候,可能我们开发人员因为项目的需要等原因并一定愿意更新xcode到最新版本.但是老版本的xcode极有可能不支持最新的iOS版本,也有一些旧的i ...
随机推荐
- Dynamics 365 Online用户密码三问及其解答
本人微信和易信公众号: 微软动态CRM专家罗勇 ,回复264或者20170903可方便获取本文,同时可以在第一间得到我发布的最新的博文信息,follow me!我的网站是 www.luoyong.me ...
- luogu【P2753】[USACO4.3]字母游戏Letter Game
这个题...一开始看了很久题目(并且问了机房几个大佬)才明白题意.. (原题入口) 题意 大概是一开始给你一些字母出现的次数 你之后组成的单词(最多两个单词)每个字母出现次数 必须小于或等于标准(st ...
- 【BZOJ4827】【HNOI2017】礼物(FFT)
[BZOJ4827][HNOI2017]礼物(FFT) 题面 Description 我的室友最近喜欢上了一个可爱的小女生.马上就要到她的生日了,他决定买一对情侣手 环,一个留给自己,一 个送给她.每 ...
- 关系型数据库工作原理-SQL解析(翻译自Coding-Geek文章)
本文翻译自Coding-Geek文章:< How does a relational database work>.原文链接:http://coding-geek.com/how-data ...
- JavaScript ES6 的let和const
1 作用域和提升 1.1 作用域(Scope) 某个变量名或者函数名,在某个程序片段中是否可见或者可访问,如果是,那么这个程序片段就是这个变量名或者函数名的作用域.比如: var name = &qu ...
- Ubuntu14.04安装pycharm用于Python开发环境部署,并且支持pycharm使用中文输入
一.目标 实现在Linux下用pycharm调试工具/Python开发 Linux使用vi/vim工具写Python,缺点:调试不方便,无代码提示.跳转等诸多功能. Windows使用idle/pyc ...
- 使用MBROSTool 工具制作U盘多启动盘的方法总结
前段时间写了一个自用五合一多启动盘分享--分别用来维护娱乐,wifi密码破解,win&mac登陆密码绕过/清除,反馈的同学还是挺多,觉得大家都有这方面的需求,于是再把自己的使用经验总结一下. ...
- 关于现在IT行业从业者一些建议
本人从事IT行业,确切的说应该是软件开发行业已经9个年头了,从刚开始小白也慢慢的已经有了自己独有的开发习惯. 近些年进入行业的人越来越多,有可能确实看到了这行业就业及薪资待遇,更多的也是随着互联网及移 ...
- LinkedList源码解析(JDK1.8)
package java.util; import java.util.function.Consumer; /** * LinkedList是List和Deque接口的双向链表的实现.实现了所有可选 ...
- javascript中的Promise使用
参考自: http://m.jb51.net/article/102642.htm 1.基本用法: (1).首先我们new一个Promise,将Promise实例化 (2).然后在实例化的promis ...