【问题标题】:How to improve branch coverage in C++如何提高 C++ 中的分支覆盖率
【发布时间】:2018-03-16 10:46:59
【问题描述】:

我有一个相当大的 C++ library 测试套件,其线路覆盖率接近 100%,但分支覆盖率只有 55.3%。浏览lcov 的结果,似乎大部分遗漏的分支都可以用C++ 的多种抛出std::bad_alloc 的方式来解释,例如每当构造 std::string 时。

我在问自己如何在这种情况下提高分支覆盖率,并认为最好有一个 new 运算符,该运算符可以配置为在命中每个错过的分支所需的尽可能多的分配之后抛出 std::bad_alloc我的测试套件。

我(天真地)尝试定义一个全局 void* operator new (std::size_t) 函数,该函数对全局 int allowed_allocs 进行倒计时,并在达到 0 时抛出 std::bad_alloc

这有几个问题:

  • 在“第一个”所需的throw 之前,很难获得new 的调用次数。我可以执行试运行来计算成功所需的调用,但是如果多个调用可能在同一行中失败,这将无济于事,例如类似std::to_string(some_int) + std::to_string(another_int) 的东西,其中每个std::to_string,通过operator+ 的连接以及初始分配可能会失败。
  • 更糟糕的是,我的测试套件(我正在使用 Catch)本身使用了很多 new 调用,所以即使我知道 我的 代码需要多少调用,也很难猜测如何测试套件的许多额外调用是必要的。 (更糟糕的是,Catch 有几种“冗长”模式,这些模式会产生大量需要记忆的输出......)

您知道如何提高分支覆盖率吗?

2017 年 10 月 7 日更新

同时,我发现https://stackoverflow.com/a/43726240/266378 带有指向 Python 脚本的链接,用于过滤由 lcov 输出中的异常创建的一些分支。这使我的分支覆盖率达到了 71.5%,但剩下的未命中分支仍然很奇怪。例如,我有几个这样的 if 语句:

有四个 (?) 分支,其中一个未命中(reference_tokenstd::string)。

有谁知道这些树枝是什么意思以及它们是如何被击中的?

【问题讨论】:

  • 你建议如何从 bad_alloc 中恢复?
  • @NeilButterworth Catch 有一个断言 CHECK_THROWS_AS,如果传递的表达式抛出特定异常,则该断言成功。
  • @MooingDuck 是的,大多数错过的分支都在没有 if/switch 的行中,但是对函数的简单分配可能会因为调用构造函数而抛出。
  • @NielsLohmann:哦,我明白了。这是有道理的。
  • @Neils 我不认为这是恢复,只是报告,即使您没有处理它,您的运行时或操作系统也可能会为您完成。我的意思是,如果你无法恢复,它可能不值得测试 - 只是失败。

标签: c++ code-coverage lcov catch-unit-test


【解决方案1】:

您要测试谁的代码 - 您的代码还是标准库?令我震惊的是,您的覆盖率报告告诉您有关“std::string”中的分支而不是您的代码。

您能否将“lcov”配置为忽略 std 库而只关注您的代码?

【讨论】:

  • 我没有找到实现这一目标的方法。
  • --exclude-throw-branches 标志可以帮助gcovr
  • @OlehPomazan 我遇到了同样的问题(由于分支覆盖率低,覆盖率为 54%)。您的解决方案解决了我的问题并提高到 87%。太感谢了!我的命令使其工作:gcovr -r . --exclude-throw-branches --xml -o coverage.xml
【解决方案2】:

前段时间我在这方面取得了成功。我没有测试套件,只是运行了我的应用程序,但发现了以下内容。

对被测事物进行某种形式的隔离很重要。我有向量和地图,当它们也容易倾斜时,它们基本上会中断测试。

当我在故障注入和故障点之间有一个 IPC 时,我认为我成功了。这允许故障注入器代码独立于被测事物进行新和删除

我在同一个二进制文件中也成功完成了类似的事情,但有两个独立的分配路径 - 一个用于故障注入代码的自定义分配器 - 确保它不会受到干扰。

我成功的系统获取了一个 malloc 的调用堆栈,并通过 IPC 将其发送到另一个程序。它决定它以前是否见过堆栈,如果没有,它分配失败。然后程序可能会崩溃和失败(核心转储被捕获),然后测试系统重新启动。 这极大地提高了我正在开发的代码的质量。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-02-20
    • 2013-12-19
    • 2012-01-11
    • 2018-10-30
    • 2019-04-08
    • 2017-06-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多