3

让我们从一个最小的工作示例开始:
main.cpp:

#include <iostream>
#include <string>

int main() {
    std::cout << "hello " + std::to_string(42);
    return 0;
}

我使用以下标志编译此代码:

[g++/clang++] -std=c++11 -g -Og --coverage -Wall -o main main.cpp

铿锵声4.0.1
gcc 4.8.5。

我只得到 50% 的代码覆盖率,因为编译器会生成未执行的异常代码,如另一个 stackoverflow 问题中所述。

问题是通过禁用异常-fno-exceptions对我来说不是一个选项。我正在为使用异常编写单元测试的代码,因此禁用所有异常不是一种选择。

为了生成我正在使用的报告gcovr,如果使用 clang++,还 llvm-cov gcov需要对其进行转换。但我不受这些工具的约束,所以如果你有其他工具不显示这种行为,请推荐它们!

基本上我需要一种方法来编译/编写此代码的单元测试,并在启用异常的情况下获得 100% 的分支/条件覆盖。有办法吗?

4

1 回答 1

1

好吧,我相信您的意图并不是实际测试这一小段代码,而是在项目中使用这个概念......

您输入的代码会引发异常 -bad_alloc当您没有剩余内存来存储将使用std::to_string. 为了 100% 安全,std::to_string应该用 包围try-catch,您可以在其中处理您的异常。

要构建 100% 的代码覆盖率单元测试,您需要强制发生异常 - 在这种特定情况下,几乎不可能保证,因为参数是一个常数。但是,在您的项目中,您可能需要分配一些大小可变的数据 - 在这种情况下,您可以在代码中隔离分配内存的方法,以单独测试它们。然后在测试函数中传递给这些方法,以评估您在 catch 块上放置的内容(并检查您是否正确处理它)。

例如,这段代码应该抛出异常,您可以在构建测试时使用它来激励自己(source):

// bad_alloc.cpp
// compile with: /EHsc
#include<new>
#include<iostream>
using namespace std;

int main() {
   char* ptr;
   try {
      ptr = new char[(~unsigned int((int)0)/2) - 1];
      delete[] ptr;
   }
   catch( bad_alloc &ba) {
      cout << ba.what( ) << endl;
   }
}

但是,如果您不打算处理bad_alloc代码中的所有异常(或绝对所有异常),则无法获得 100% 的覆盖率——因为它不会被 100% 覆盖......大多数情况下,真正的 100不过,% 覆盖率是不必要的。

于 2017-09-22T15:26:37.853 回答