我正在使用lcov 2.0检查我的gtest分支覆盖率,但我遇到了许多由STD引起的分支,例如下面
emplace/insert/operator[]
中的std::map
。
这是我的源代码
// 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[]
函数内部的异常之间有关系吗?我应该如何在这些函数中引发异常?
你是对的,未覆盖的树枝是投掷路径。运行 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
的构造函数中抛出异常。