去年写的文章,搬到cnblog

本文所述的方法只对xcode5做过测试,xcode6是否可行尚未可知。

  1. 配置编译选项

    首先请参考苹果官方的文档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文件。

  2. 收集运行时数据

    程序运行的时候,会自动记录覆盖率相关的数据,但是这个数据只有在程序正常退出的时候才会写到文件。

    对于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文件。
  1. 转换数据

    这一步是将收集的数据转换成可读的形式,使用一个开源库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命令即可。
  1. 如何针对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命令即可。
  1. 与单元测试相结合

    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进行代码覆盖率测试的更多相关文章

  1. iOS代码覆盖率测试工具

    基于lcov-1.11的:CodeCoverage4iOS   阅读目录 环境准备 Xcode工程配置 构建并安装程序 收集代码覆盖率 过滤结果 合并多个Coverage.info⽂件⽣成覆盖率报告: ...

  2. Xcode真机测试could not find developer disk image解决方法

    原文地址:http://my.oschina.net/u/2340880/blog/521700 Xcode真机测试could not find developer disk image解决方法 在使 ...

  3. WWDC15 Session笔记 - Xcode 7 UI 测试初窥

    https://onevcat.com/2015/09/ui-testing/ WWDC15 Session笔记 - Xcode 7 UI 测试初窥 Unit Test 在 iOS 开发中已经有足够多 ...

  4. Xcode 真机测试破解方法(转加修改)xcode 4.3 通过

    Xcode 真机测试破解方法(转加修改)xcode 4.3 通过 生成本机证书 应用程序->实用工具->钥匙串访问 菜单:钥匙串访问->证书助理->创建证书, 然后按以下图片顺 ...

  5. VS2015+NUnit+OpenCover 完成单元测试代码覆盖率测试

    1.VS2015+NUnit+OpenCover 完成单元测试代码覆盖率测试 https://download.csdn.net/download/qq_39441918/10522539 2.*注意 ...

  6. Spring Boot 代码覆盖率测试

    代码覆盖率测试是规范软件开发流程里一个必不可少的环节.一般都是在PG末尾阶段,伴随着IT自测产生. ↑以上,是自己yy出来的啊,反正我司是这样要求的.不跑覆盖率,鬼知道你在代码里夹杂了一些什么东西. ...

  7. 使用Cobertura做代码覆盖率测试

    经验总结:首先要把cobertura.jar包含ant的classpath路径中,其次要求它包含在测试用例的classpath中: 使用cobertura做代码覆盖率测试中出现的问题:覆盖率始终为0, ...

  8. 解决Xcode真机测试时ineligible devices的问题

    升级了Xcode到6.3,连接真机测试时,出现不能选择设备.如图: 设备系统版本是8.3的,Xcode连接其他低系统版本的设备做真机测试时就不会有这个问题. 有人说这是Xcode6.3的bug. 我的 ...

  9. Xcode真机测试could not find developer disk image解决方法(支持iOS9.2)

    这个问题开发者经常碰到,因为当我们更新手机iOS版本的时候,可能我们开发人员因为项目的需要等原因并一定愿意更新xcode到最新版本.但是老版本的xcode极有可能不支持最新的iOS版本,也有一些旧的i ...

随机推荐

  1. CASE WHEN用法

    问题:假如说这个条件有一条数据不满足,那么那条数据就不会读出来,,那么,我怎么才能把它读出并且赋值为空呢 方法: SELECT `s`.*, ( CASE THEN SUM(a.total_numbe ...

  2. 使用myeclipse出现中文乱码的情况以及解决办法

    一:在jsp页面使用中文在浏览器中显示的时候出现乱码,解决问题的办法: 1)直接在<mete>标签中修改charset属性为"utf-8"或者为"gb2312 ...

  3. 严格次小生成树(Bzoj1977:[Beijing2010组队]次小生成树)

    非严格次小生成树 很简单,先做最小生成树 然后枚举没加入的边加入,替换掉这个环内最大的边 最后取\(min\) 严格次小生成树 还是一样的 可以考虑维护一个严格次大值 最大值和枚举的边相同就替换次大值 ...

  4. [BZOJ1007] [HNOI2008] 水平可见直线 (凸包)

    Description 在xoy直角坐标平面上有n条直线L1,L2,...Ln,若在y值为正无穷大处往下看,能见到Li的某个子线段,则称Li为可见的,否则Li为被覆盖的. 例如,对于直线:L1:y=x ...

  5. iOS开发--XMPPFramework--框架的导入(二)

    创了一个XMPP即时通讯交流群140147825,欢迎大家来交流~我们是一起写代码的弟兄~ xmpp协议开发即时通讯,最常用的就是XMPPFramework. 第一种方法,是直接拖进项目 1.可以下载 ...

  6. Tomcat 请求处理流程详解

    Overview Connector 启动以后会启动一组线程用于不同阶段的请求处理过程. Acceptor 线程组.用于接受新连接,并将新连接封装一下,选择一个 Poller 将新连接添加到 Poll ...

  7. Gson解析json字符串、json数组转换成对象

    实体类: public class Product { private int id; private String name; private String date; public int get ...

  8. 关于KPM算法

    [转]从头到尾彻底理解KMP http://blog.csdn.net/v_july_v/article/details/7041827 int* GetNextval(char* p){ int p ...

  9. Php显示中文时乱码

    <?php echo "你们好哈"; ?> 显示乱码,解决办法 <?php header("content-type:text/html; charse ...

  10. Unity3D脚本的生命周期(执行顺序)

    Unity脚本中有许多固定的函数 例如Start();Update(); 而这些函数都有固定的执行顺序 搞清楚这些函数的执行顺序 对于我们理清代码的逻辑就显得尤为重要 举个简单的例子 //脚本A pu ...