如何减少此代码中包含std::string operator+的未覆盖分支?

How could I reduce uncovered branches in this code contains std::string operator+?

提问人:musnow 提问时间:11/14/2023 最后编辑:musnow 更新时间:11/14/2023 访问量:69

问:

我正在使用 lcov2.0 检查我的测试分支覆盖率,遇到了这个问题。

// source code
void test_string_plus(const string& local ,const string& remote)
{
    static string recv_msg;
    static_cast<void>(recv_msg.assign("/" + (local < remote ? local + "_" + remote : remote + "_" + local)));
}
// test code
TEST(teststring, teststringplus)
{
    string local = "test1";  
    string remote = "test12";
    EXPECT_NO_THROW(test_string_plus(local, remote));
    local = "test21";
    remote = "test2";  
    EXPECT_NO_THROW(test_string_plus(local, remote));
}

它在 lcov 中报告如下

     281                 :           2 : void test_string_plus(const string& local ,const string& remote)
     282                 :             : {
     283                 :           2 :     static string recv_msg;
     284   [ +  +  +  -  :           2 :     static_cast<void>(recv_msg.assign("/" + (local < remote ? local + "_" + remote : remote + "_" + local)));
          +  -  +  -  +  
          -  +  -  +  +  
          +  +  -  -  -  
                      - ]
     285                 :           2 : }

GCOV 文件显示,此代码包含许多带有 throw 的未覆盖分支。

        2:  284:    static_cast<void>(recv_msg.assign("/" + (local < remote ? local + "_" + remote : remote + "_" + local)));
call    0 returned 2
branch  1 taken 1 (fallthrough)
branch  2 taken 1
call    3 returned 1
branch  4 taken 1 (fallthrough)
branch  5 taken 0 (throw)
call    6 returned 1
branch  7 taken 1 (fallthrough)
branch  8 taken 0 (throw)
call    9 returned 1
branch 10 taken 1 (fallthrough)
branch 11 taken 0 (throw)
call   12 returned 1
branch 13 taken 1 (fallthrough)
branch 14 taken 0 (throw)
call   15 returned 2
branch 16 taken 2 (fallthrough)
branch 17 taken 0 (throw)
call   18 returned 2
call   19 returned 2
call   20 returned 2
branch 21 taken 1 (fallthrough)
branch 22 taken 1
call   23 returned 1
branch 24 taken 1 (fallthrough)
branch 25 taken 1
call   26 returned 1
call   27 never executed
branch 28 never executed
branch 29 never executed
call   30 never executed
branch 31 never executed
branch 32 never executed
call   33 never executed
        2:  285:}

我使用的工具版本和命令。

  • g++/gcov (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0
  • gtest 1.12.x
  • lcov/genhtml:LCOV 版本 2.0-1
    g++ -std=c++17 test.cpp -o test -lgtest -lgtest_main -pthread -fprofile-arcs -ftest-coverage -fprofile-update=atomic && \
    ./test && \
    gcov -b -c -o . test.cpp && \
    lcov --capture \
         --rc branch_coverage=1 \
         --directory . \
         --filter branch \
         --output-file coverage_all.info \
         --ignore-errors mismatch && \
    genhtml coverage_all.info \
            --rc branch_coverage=1 \
            --output-directory coverage_report && \
    rm *.info

我已经习惯忽略了一些无法访问的分支--filter branch


我应该如何减少这里未覆盖的树枝?或者我可以忽略它们吗?

https://legacy.cplusplus.com/reference/string/string/operator+/

我在 std::string 中检出引用。 似乎只有在尝试添加超过长度限制的字符串或内存应用程序失败时才会抛出异常,但在实际项目中,构造这样的测试条件是非常不合理的。operator+()


我试图修改为,如果不然,那些由字符串引起的分支可以被过滤。?:

    281                 :           2 : void test_string_plus(const string& local ,const string& remote)
     282                 :             : {
     283                 :           2 :     static string recv_msg;
     284                 :           2 :     string target("/");
     285         [ +  + ]:           2 :     if(local<remote)
     286                 :             :     {
     287                 :           1 :         target += local + "_" + remote;
     288                 :             :     }
     289                 :             :     else{
     290                 :           1 :         target +=  remote + "_" + local;
     291                 :             :     }
     292                 :           2 :     static_cast<void>(recv_msg.assign(target));
C++ GoogleTest GCov LCOV

评论

1赞 Ext3h 11/14/2023
测试的黄金法则是什么?测试您自己的代码,而不是第三方库。如果您为第三方库编写测试 - 其中包括属于上游而不是其他地方的 STL。也就是说,使用 gcov 然后挂断 STL 并不是一个好方法。你对这个例外是正确的,但甚至比你能够轻松涵盖的要复杂得多。std::string
0赞 musnow 11/14/2023
感谢。我明白你的意思,所以我计划降低分支机构的覆盖要求。目前看来,即使使用。--filter branch
1赞 Swift - Friday Pie 11/14/2023
全球很糟糕。很有可能你通过省略这些(很难跟踪)来触发分析器,或者只是编译错误——将其与广泛的宏系统或大型代码库相结合,往往会产生意想不到的结果。using namespace std;std::
0赞 musnow 11/14/2023
@Swift-FridayPie 谢谢,我这样做是因为发布的代码仅用于LCOV测试,而不是实际的项目代码。
0赞 Swift - Friday Pie 11/15/2023
哦!我曾经遇到过这样的奇怪的不可追踪的问题,从那时起,我使用自己的类型字典(例如)。关于....至少在重新分配或从小对象变为常规对象时,它确实会抛出。使用替代的非投掷分配器或优化操作可能会有所帮助。using String = std::string;std::string

答: 暂无答案