4

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

在此处输入图像描述

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

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

但这有几个问题:

  • new在“第一个”期望之前,很难获得呼叫次数throw。我可以执行试运行来计算成功所需的调用,但是如果多个调用可能在同一行中失败,例如std::to_string(some_int) + std::to_string(another_int)where each std::to_string、连接 viaoperator+以及初始分配可能失败,这将无济于事。
  • 更糟糕的是,我的测试套件(我正在使用 Catch)new本身使用了很多调用,所以即使我知道我的代码需要多少调用,也很难猜测测试套件需要多少额外的调用。(更糟糕的是,Catch 有几种“冗长”模式,它们会创建大量再次需要内存的输出......)

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

2017-10-07 更新

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

带有未命中分支的 if 语句

有四个(?)分支,其中一个未命中(reference_token是 a std::string)。

有谁知道这些分支的含义以及它们是如何被击中的?

4

2 回答 2

1

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

您可以将“lcov”配置为忽略标准库并只关注您的代码吗?

于 2017-10-05T06:06:05.217 回答
0

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

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

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

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

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

于 2017-10-04T22:45:56.103 回答