代码改变世界

收集iOS程序的代码覆盖率

2012-08-01 11:41  知平软件  阅读(5332)  评论(5编辑  收藏  举报

前面讲到<收集Android程序的代码覆盖率 >的时候,讲到收集代码覆盖率分别有修改最终程序(例如Emma是修改字节码),和修改源文件两种方式。而在iOS上,采用的就是后者,iOS原来用的是gcov收集代码覆盖率,后面苹果的LLVM项目,也实现了代码覆盖率收集功能,用法完全兼容gcov,而且生成的代码覆盖率统计文件的格式也兼容gcov。

先说说怎样收集ios程序的代码覆盖率,然后再说说原理性的东西。

不知道大家用的是xcode的哪个版本?老版本的xcode使用的clang编译器的代码覆盖率功能好像坏掉了……也就是说按照苹果的文档去做,生成的程序在启动的时候会崩溃。在最新的clang编译器里,已经修复了这个缺陷,下面是做法:

1.    首先下载LLVM的最新源码(LLVM是一个开源项目 ,需要SVN客户端,在终端中运行):
svn co http://llvm.org/svn/llvm-project/llvm/trunk llvm
2.    在同步clang的源代码:
cd llvm/tools
svn co http://llvm.org/svn/llvm-project/cfe/trunk clang
3.    代码同步完毕后,编译编译器:
cd..
# 指定将我们编译的clang安装到opt文件夹中
./configure --prefix=/opt --enable-optimized
# 是用8个线程并行编译
make -j8
# 将结果程序安装到/opt文件夹中
sudo make install

编译好了以后,需要告诉xcode使用最新的编译器,而不是它自带的坏掉的编译器。在Xcode里打开工程:
1.    设置User Defined Build Setting:CC = /opt/bin/clang,这一步告诉xcode使用我们的编译器,如果大家熟悉make的话,应该知道CC是一个很出名的make变量。如下图所示:
 xcode_cov_cc

2.    设置Other C Flags: --coverage,这一步告诉clang在编译时,生成代码覆盖率版本。如下图所示:
xcode_cov_cflags
3.    设置Other Linker Flags: --coverage -lprofile_rt,这一步告诉clang在链接时,需要连接收集代码覆盖率用到的函数库。 如下图所示:
 xcode_cov_linkflags

设置好以后,编译,然后在模拟器里或者手机里执行手工或自动化测试,测试完毕后,代码覆盖率信息就已经保存好了,看的话,需要一个工具CoverStory,CoverStory是用来看gcov生成的代码覆盖率信息的,但因为clang完全兼容gcov,所以也就可以复用这个工具,下载地址是:http://code.google.com/p/coverstory/

而代码覆盖率信息是放在一个非常隐晦的地方(说实话那个地方我很久以来只会通过终端进入,一直都没找到从GUI界面进去的方式):

# ~代表用户的家 (Home)目录,由于我用的是模拟器,因此下面的路径里用的是Debug-iphonesimulator,如果是用真机
# 机 ,应该是Debug-iphoneos文件夹。 
~/Library/Developer/Xcode/DerivedData/<你的ios工程名加上一堆随机字符>/Build/Intermediates/<工程名.build>/Debug-iphonesimulator/<工程名.build>/Object-normal/<cpu 架构>/

以我得机器为例,我的工程如上图所示是CoreDataBooks,因此路径是:
shiyimin-Mac-2:i386 shiyimin$ pwd
/Users/mahmood1/Library/Developer/Xcode/DerivedData/CoreDataBooks-dpmulgzuyflwiycpkobgmstmioxz/Build/Intermediates/CoreDataBooks.build/Debug-iphonesimulator/CoreDataBooks.build/Objects-normal/i386

在Finder里将这个目录拖到CoverStory里,就可以看到具体的代码覆盖率信息了:

cover_story
 
从上图可以看到,最左边的列表里,显示了ios程序各源代码的代码覆盖率比例,例如CoreDataBooksAppDelegate.m这个文件的覆盖率就只有52.9%,右边红色高亮显示了在测试中未覆盖到的代码,而已覆盖的代码以黑色显示。

如果你把文件夹拖到CoverStory里,没有任何反应,可以在查看文件夹里是否有.gcda和.gcno文件来排错,如果没有这两种文件,那一般说明没有收集到代码覆盖率信息。
xcode_cov_troubleshooting

最后,有关gcov的使用和原理,请参看gcov文档:http://gcc.gnu.org/onlinedocs/gcc/Gcov.html 

本文由知平软件施懿民编写,请关注我们的微博