使用块的XCode 5.1单元测试覆盖率分析失败

时间:2014-03-12 06:33:49

标签: xcode gcov lcov xcode5.1 test-coverage

今天我的任务是将单元测试覆盖率分析添加到我们的代码库中。今天也是iOS 7.1与XCode 5.1一起发布的日子。从发行说明:

  

已重新实现用于代码覆盖率测试的gcov工具。新版本使用LLVM项目中的llvm-cov工具。对于所有重要功能,它在功能上等同于旧版本。 Xcode中gcov的位置也已移动,使用xcrun来调用它。如果您发现问题,请提交错误报告。对于此版本,您仍然可以使用GCC的旧版gcov,它以gcov-4.2的形式提供。 11919694已更新

我只是在跟踪了几个instructional blog posts后才意识到这一点,正确设置我的环境 - 在测试时在模拟器的构建文件夹中生成.gcda / .gcno文件 - 并且报告生成工具here尝试将它们解析为报告。 (这是一个./getcov脚本,它收集您的环境变量以传递给lcov-1.10脚本以生成报告)

第一个障碍是新的捆绑gcov程序不支持-v参数来获取版本,这是lcov初始化的第一步。看起来就像一个非首发,但阅读上面的发行说明我修改了lcov脚本以使用旧的gcov-4.2版本并解决了这个问题。

但是,lcov在处理我的覆盖数据文件时很早就出错了。这会在我的项目中按字母顺序生成一个可能包含前10个文件的报告。不是特别有用。错误输出是最小的,也是无益的:

  

geninfo:错误:GCOV(build_artifacts)/(class_that_errored).gcda失败了!

我修改了lcov脚本以打印它所获得的错误(遗憾的是,它只产生了11,在gcov(-io).c代码中找不到任何引用)并继续操作而不是退出,所以我在报告中留下了更多的文件,但仍然可能有85%的源文件出错了。

我能够在报告中成功结束的文件与发生错误的文件之间辨别的唯一模式是任何使用内联块声明的文件都失败了。没有任何传递过的文件以任何方式阻止,我检查过的所有文件都包含块。奇怪。

然后我发现我可以打开CoverStory中的各个.gcda文件,包括那些在lcov脚本中出错的文件。在coverage报告下方的消息窗口中,所有出错的文件都有警告消息:

  

(class_that_errored).gcno:'__copy_helper_block _'没有行

     

(class_that_errored).gcno:'__destroy_helper_block _'没有行

此时我最好的假设是新的XCode 5.1正在生成旧的gcov-4.2程序无法处理有关块声明的.gcda文件。

但是我已经筋疲力尽了我想要尝试的一切,所以我在这里询问是否有人知道我错过了什么,或者有什么想法可以进一步调试。或者,如果有人从今天的XCode 5.1更新中成功测量了测试覆盖率,那么我很乐意听到您必须做出的任何更改。

4 个答案:

答案 0 :(得分:13)

问题出在LCOV 1.10 geninfo 脚本中。它测试当前版本的gcov。它通过解析版本字符串来完成此操作。由于gcov现在指向llvm-cov,因此版本字符串的解析不正确。

解决方案是修改 geninfo 的get_gcov_version()子程序。在第 1868 行中,将-v更改为--version。然后将行 1874 替换为:

if ($version_string =~ m/LLVM/)
{
    info("Found llvm-cov\n");
    $result = 0x40201;
}
elsif ($version_string =~ /(\d+)\.(\d+)(\.(\d+))?/)

修改后的子程序应如下所示:

sub get_gcov_version()
{
    local *HANDLE;
    my $version_string;
    my $result;

    open(GCOV_PIPE, "-|", "$gcov_tool --version")
        or die("ERROR: cannot retrieve gcov version!\n");
    $version_string = <GCOV_PIPE>;
    close(GCOV_PIPE);

    $result = 0;
    if ($version_string =~ m/LLVM/)
    {
        info("Found llvm-cov\n");
        $result = 0x40201;
    }
    elsif ($version_string =~ /(\d+)\.(\d+)(\.(\d+))?/)
    {
        if (defined($4))
        {
            info("Found gcov version: $1.$2.$4\n");
            $result = $1 << 16 | $2 << 8 | $4;
        }
        else
        {
            info("Found gcov version: $1.$2\n");
            $result = $1 << 16 | $2 << 8;
        }
    }
    return ($result, $version_string);
}

注意: 确保--gcov-tool 设置为gcov-4.2。< / EM>

答案 1 :(得分:2)

而不是修改geninfo我创建了一个llvm-cov-wrapper脚本并使用了lcov&#39; --gcov-tool命令行选项:

#!/bin/bash
# llvm-cov wrapper to make it behave more like gcov

if [ "$1" = "-v" ]; then
    echo "llvm-cov-wrapper 4.2.1"
    exit 0
else
    /usr/bin/gcov $*
fi

答案 2 :(得分:2)

实际上我注意到lcov正在使用-b选项调用gcov,而gcov-4.2将在此选项上崩溃(引发分段错误)。如果我从getinfo中删除-b选项,那么即使它仍然显示一些错误信息,仍然可以生成gcov文件。

这可能就是为什么covertory仍然可以提供覆盖输出。所以我想解决方法是从lcov中删除-b选项。并且如您所建议的那样,忽略getinfo中的错误

答案 3 :(得分:0)

对于此线程的新用户,请注意lcov-1.11已经用完。这消除了gcov -v兼容性的问题。但是,我正在使用XCode 6.1并且仍然在某些文件上出现错误。

geninfo: WARNING: /Users/XXX/MyFile.gcno: found unrecognized record format - skipping

请注意,您可以添加--ignore-errors graph来跳过这些错误,但问题并未真正解决。