【问题标题】:Visual Studio gives partial code coverage for new initializersVisual Studio 为新的初始化程序提供部分代码覆盖
【发布时间】:2017-12-15 01:46:13
【问题描述】:

我正在使用Visual Studio 2015 Update 3

我无法在这个简单的Unit Test 上获得 100% 的代码覆盖率:

TEST_METHOD(New)
{
    int* test = new int(4); //shows the line as partially covered
    int* test2 = new int;   //shows line as 100% covered
}

如果语句也在测试函数调用的代码中,就会发生这种情况。

与项目默认设置不同的唯一设置是/profile 开关,这是让任何代码覆盖率首先工作所必需的。

我注意到 new 在没有 initializer 的情况下使用时会显示 100% 覆盖率,但对于类,我通常会立即初始化它们,并且我想找到一种方法来做到这一点而不会减少代码覆盖率。

代码反汇编

                int* test = new int(4); //shows the line as partially covered
0F951D53  push        4  
0F951D55  call        operator new (0F9512B2h)  
0F951D5A  add         esp,4  
0F951D5D  mov         dword ptr [ebp-0ECh],eax  
0F951D63  cmp         dword ptr [ebp-0ECh],0  
0F951D6A  je          UnitTest1::UnitTest1::New+56h (0F951D86h)  
0F951D6C  mov         eax,dword ptr [ebp-0ECh]  
0F951D72  mov         dword ptr [eax],4  
0F951D78  mov         ecx,dword ptr [ebp-0ECh]  
0F951D7E  mov         dword ptr [ebp-100h],ecx  
0F951D84  jmp         UnitTest1::UnitTest1::New+60h (0F951D90h)  
0F951D86  mov         dword ptr [ebp-100h],0  
0F951D90  mov         edx,dword ptr [ebp-100h]  
0F951D96  mov         dword ptr [test],edx  
            int* test2 = new int;   //shows line as 100% covered
0F951D99  push        4  
0F951D9B  call        operator new (0F9512B2h)  
0F951DA0  add         esp,4  
0F951DA3  mov         dword ptr [ebp-0F8h],eax  
0F951DA9  mov         eax,dword ptr [ebp-0F8h]  
0F951DAF  mov         dword ptr [test2],eax  

查看代码,我猜jmp 语句会导致代码覆盖率分析工具将某些语句视为未命中。

【问题讨论】:

  • 忽略以前的 cmets。我混淆了“new with initializer”和“array new”!
  • 试着看一下程序集,看看有没有什么意外的跳转什么的。
  • @MartinBonner 我刚刚添加了它,我怀疑两个跳跃之一可能是原因,但我不知道如何解决它。

标签: c++ unit-testing visual-studio-2015 code-coverage


【解决方案1】:

您似乎有一个选项,这意味着new 始终表现为new(nothrow)(换句话说,如果分配失败,new 返回nullptr)。

程序集正在检查 operator new 是否返回了 nullptr(如果是,则不在返回的地址存储 4)。您需要测试分配失败的情况才能完全覆盖。在 C++ 中,程序集如下所示:

    int * test;
    int * tmp = operator new(sizeof(int));
    if (tmp != nullptr) {
        *tmp = 4;
        test = tmp;
    } else {
        test = nullptr;
    }

编辑

啊哈!在this blog post Microsoft 中解释说,为 new 生成的代码一直在测试是否返回 null,以防万一您链接到 nothrow 版本。在 VC2015 中,他们提供了一个选项,可以说“不要打扰,new 会抛出,它永远不会返回 nullptr

因此,为避免不必要的分支,请在编译选项中添加:/Zc:throwingNew。 (这通常也有助于提高性能。)

【讨论】:

  • 所以没有简洁的方法可以将其标记为完全覆盖?我已经在测试将nullptr 发送到我正在使用的函数的情况。
  • 谢谢,我已经搜索了微软的网站,但没有找到这个,你的 Google-fu 处于不同的级别。接受你的回答。
猜你喜欢
  • 1970-01-01
  • 2016-09-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多