为什么我的单元测试没有覆盖到任何行而 gcov 没有报告任何行被覆盖?

15

我正在使用 Xcode 3.2 在 10.6 上,使用预装的 gcov 和默认的 GCC 编译器(版本均为 4.2.1)。我创建了一个依赖 Cocoa 单元测试框架的程序包,并按照苹果文档 设置了 gcov 检测的构建配置,基于没有启用任何编译器优化的 Debug 配置。

当我使用这个“Gcov-instrumented”配置构建测试程序包时,应用程序启动并注入和运行测试。此外,覆盖率统计文件生成在以下位置:

build/<AppTarget>.build/Gcov-instrumented/<AppTarget>.build/Objects-normal/x86_64/<object>.gcda

build/<AppTarget>.build/Gcov-instrumented/<AppTarget>.build/Objects-normal/x86_64/<object>.gcno

到目前为止都很好。我知道测试确实已经运行,因为如果我插入失败,则测试套件会按预期失败。不幸的是,gcov 报告说没有一行对象被测试覆盖!每一行都报告为 0 覆盖率。我已经在这里和苹果邮件列表档案中搜索过,但找不到任何类似的问题。我想我肯定漏掉了什么 - 但是它是什么呢?

5个回答

10

我时不时地遇到这个问题。在我的主要项目中,我运行了一段幸运的时间,在大部分时间里,“基本工作正常”。我的意思是说,我能够显示出覆盖率,但相较于10.5版本,需要付出更多的努力。例如,我必须积极删除覆盖文件并重新构建才能获取任何更新。即使在“几乎无法工作”的状态下,编译器/运行时似乎也不愿意覆盖现有的覆盖数据文件。

我认为我已经又发现了一个可行的场景。这肯定是巫术,也不是最理想的:

  1. 确保SDK是10.6。
  2. 确保部署设置为gcc 4.0 (!)。
  3. 对项目进行完全清除。
  4. 重新构建。

这样能让你得到预期的覆盖数据吗?

当然,我期望能够使用gcc 4.2或其中一个LLVM编译器生成有效的覆盖文件,但目前看来,这比以前稍微好一些。

另一个线索:当我观察覆盖数据(使用Google的Cover Story)时,我会收到警告,如:

/BUILDRESULTS/MarsEdit.build/Code Coverage/MarsEditDataModelTests.build/Objects-normal/i386/MEDataItem.gcno:version '400A', prefer '402*'

但仍然呈现出了覆盖信息。因此,它似乎对旧版本的覆盖格式版本感到困惑,但如果我使用新的编译器(4.2),它将生成新格式的.gcno文件,那么0%的覆盖率问题就像Graham一样困扰着我。


谢谢您!我现在得到了我期望的覆盖率 :-) - user23743
1
我用相同的方法在Snow Leopard上使其工作了。然而,需要降级到GCC 4.0的要求有些令人不安,因为必须使用GCC 4.2或LLVM编译的代码(例如使用Blocks的代码)将无法在旧版本编译器中运行,代码覆盖率也可能会消失。这听起来像是一个等待被提交的Radar... - Quinn Taylor
Daniel,当我使用lcov生成HTML覆盖率报告时,遇到了类似的问题。它允许我传递--gcov-tool /usr/bin/gcov-4.0来覆盖默认值4.2,该值指向/usr/bin/gcov。我窥视了CoverStory的源代码,它正在使用此符号链接。http://code.google.com/p/coverstory/source/browse/trunk/CoverStoryDocument.m#131 即使它不在首选项对话框中,如果他们添加用户默认设置,那就太好了... - Quinn Taylor
Quinn,你在哪里输入 --gcov-tool /usr/bin/gcov-4.0 标志?我已经尝试将其设置为链接器标志,但是当我编译时,Xcode会抛出一个错误。当我尝试使用此标志从命令行进行gcc编译时,它也会抛出一个错误:ld: warning: in /usr/bin/gcov-4.0, missing required architecture x86_64 in file - John Gallagher
@danielpunkass 直到我开始使用块,就不能使用GCC 4.0了 :( - user23743
@quinntaylor 最新版本的Coverstory应该会为您确定gcc版本标志。 - dmaclach

7
在Xcode 4.6中,覆盖率报告似乎只需要设置 "生成测试覆盖文件" 和 "仪表程序流" 就行了。运行测试后,将覆盖工具指向输出文件夹。 输出文件夹在 ~/Library/Developer/Xcode/Derived Data/<Project>-<hash>/Build/Intermediates/<Target>.build/Debug-iphonesimulator/<Target>.build;在CoverStory中打开该文件夹即可查看结果。
GitHub存储库包含脚本,可以自动发现输出并使用lcov进行可视化处理。我目前使用的是CoverStory,感觉还不错。

我的.gcda和.gcdo文件路径略有不同:~/Library/Developer/Xcode/Derived Data/<Project>-<hash>/Build/Intermediates/<Target>.build/Debug-iphonesimulator/<Target>.build/Objects-normal/i386 - Marco

2
您可以使用gcc 4.2.1来实现代码覆盖率。详情请参见以下链接:SnowLeopardGCov

该页面的内容已被替换(截至6月4日),显示“此页面已过时。这些信息已整合到Google Toolbox For Mac Wiki中。”并提供指向http://code.google.com/p/google-toolbox-for-mac/wiki/SnowLeopardGCov的链接。 - Peter Hosey
修复了新的改进链接。谢谢Peter。 - dmaclach
对我来说没有用。我将编译器设置为4.2,删除了前缀头文件,并对单元测试目标进行了完全的清理构建。我根本没有得到任何覆盖率信息。 - user23743
嘿,Graham。我假设你也为目标打开了“仪器程序流”和“生成测试覆盖文件”的标志? - dmaclach
Graham,请确保你在iOS 4.0上正确退出。更多信息请参见:http://code.google.com/p/google-toolbox-for-mac/wiki/iOSGCov - dmaclach

0

我一直在尝试让iPhone模拟器的代码覆盖率工作,但总是得到0%的覆盖率。以下是配置细节和我尝试过的步骤。

配置

Xcode 3.2.5/iOS 4.1和iOS 4.2/Mac 10.6/GCC 4.2应用程序 UICatalog

参考资料

http://www.cubiclemuses.com/cm/articles/2009/05/14/coverstory-on-the-iphone/

http://developer.apple.com/library/mac/#qa/qa2007/qa1514.html

步骤

  • 启用“生成测试覆盖文件”
  • 启用“仪器程序流程”
  • 将“-lgcov”添加到“其他链接器标志”中
  • 在Info.plist中设置UIApplicationExitsOnSuspend标志为true

结果

我已经生成了.gcda文件,但覆盖率始终显示为0%。

尝试的设置

1. 将GCC更改为4.0和4.2。当我尝试将GCC更改为4.0时,出现了26个构建错误。
2. 设置环境变量: ``` const char *prefix = "GCOV_PREFIX"; const char *prefixValue = [[NSHomeDirectory() stringByAppendingPathComponent:@"Documents"] cStringUsingEncoding:NSASCIIStringEncoding]; // 这会获取应用程序的文档目录的文件路径 const char *prefixStrip = "GCOV_PREFIX_STRIP"; const char *prefixStripValue = "1"; setenv(prefix, prefixValue, 1); // 这会设置一个告诉gcov将.gcda文件放在哪里的环境变量。 setenv(prefixStrip, prefixStripValue, 1); // 这会告诉gcov去掉默认前缀,并使用我们刚刚声明的文件路径。 ```
3. 将GCC优化设置为无(-O0),并取消选中预编译前缀头文件标志。

0

当静态库的*.gcno文件被共享库的文件覆盖时,我的测试覆盖率为0。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接