lcov 分支覆盖,在 std::map 中放置/插入

问题描述 投票:0回答:1

我正在使用lcov 2.0检查我的gtest分支覆盖率,但我遇到了许多由STD引起的分支,例如下面

emplace/insert/operator[]
中的
std::map

  • g++ (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0
  • gtest 1.12.x
  • lcov/genhtml:LCOV 版本 2.0-1

这是我的源代码

// src/main.hpp
#include <cstdint>
#include <iostream>
#include <map>
#include <set>
#include <stdexcept>
using namespace std;

class mytestint
{
public:
    mytestint() = default;
    mytestint(uint16_t id, uint16_t pr) : _id(id), _pr(pr) {}

    uint16_t get_id() const
    {
        return _id;
    }

private:
    uint16_t _id;
    uint16_t _pr;
};

map<uint16_t, mytestint> _test_map;
map<uint16_t, uint16_t> _test_map_pod;

void test_emplace(uint16_t id, uint16_t pr)
{
    // map with class
    mytestint temp = {id, pr};
    auto t = _test_map.emplace(id, temp);
    auto k = _test_map.emplace(id, mytestint(id,pr));
    auto s = _test_map.insert({pr, temp});
    _test_map[id] = temp;
    auto h = _test_map[pr];
    // map with uint16_t
    _test_map_pod.emplace(id,pr);
    _test_map_pod.insert({pr,id});
    _test_map_pod[id] = pr;
}

这是我的gtest代码

#include "src/main.hpp"
#include <gtest/gtest.h>

TEST(MapTest, TestMap) {
    EXPECT_NO_THROW(test_emplace(1,1));
    EXPECT_NO_THROW(test_emplace(2,2));
    EXPECT_NO_THROW(test_emplace(3,3));
    EXPECT_NO_THROW(test_emplace(2,4));
}

int main(int argc, char **argv) {
    ::testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}

lcov 将显示对这些函数的所有调用都有未处理的分支。

      92                 :           4 : void test_emplace(uint16_t id, uint16_t pr)
      93                 :             : {
      94                 :             :     // map with class
      95                 :           4 :     mytestint temp = {id, pr};
      96         [ +  - ]:           4 :     auto t = _test_map.emplace(id, temp);
      97         [ +  - ]:           4 :     auto k = _test_map.emplace(id, mytestint(id,pr));
      98         [ +  - ]:           4 :     auto s = _test_map.insert({pr, temp});
      99         [ +  - ]:           4 :     _test_map[id] = temp;
     100         [ +  - ]:           4 :     auto h = _test_map[pr];
     101                 :             :     // map with uint16_t
     102         [ +  - ]:           4 :     _test_map_pod.emplace(id,pr);
     103         [ +  - ]:           4 :     _test_map_pod.insert({pr,id});
     104         [ +  - ]:           4 :     _test_map_pod[id] = pr;
     105                 :           4 : }

这是我生成 lcov 报告的命令。

    g++ -std=c++17 test.cpp -o test -lgtest -lgtest_main -pthread -fprofile-arcs -ftest-coverage -fprofile-update=atomic && \
    ./test && \
    gcov -o . test.cpp && \
    lcov --capture \
         --rc branch_coverage=1 \
         --directory . \
         --output-file coverage_all.info \
         --ignore-errors mismatch && \
    lcov --remove coverage_all.info '*/usr/include/*' '*/usr/lib/*' '*/usr/lib64/*' \
                                    '*/usr/local/include/*' '*/usr/local/lib/*'     \
                                    '*/usr/local/lib64/*'   \
        --rc branch_coverage=1 \
        --output-file coverage.info \
        --ignore-errors unused \
        --ignore-errors mismatch && \
    genhtml coverage.info \
            --rc branch_coverage=1 \
            --output-directory coverage_report 

我想知道这些未覆盖的分支有什么解决办法吗?

这里未覆盖的分支和

emplace/insert/operator[]
函数内部的异常之间有关系吗?我应该如何在这些函数中引发异常?

c++ googletest lcov
1个回答
0
投票

你是对的,未覆盖的树枝是投掷路径。运行 gcov

gcov -b -c -o . test.cpp

您将在

.gcov
文件中看到类似以下内容

        4:   12:    auto t = _test_map.emplace(id, temp);
call    0 returned 4
branch  1 taken 4 (fallthrough)
branch  2 taken 0 (throw)

这里很难手动引发异常。一种可能的解决方案是在

mytestint
的构造函数中抛出异常。

© www.soinside.com 2019 - 2024. All rights reserved.