生成单元测试覆盖率
前文提到添加了编译参数 -fprofile-arcs
、 -ftest-coverage
已经生成了gcno
文件,单元测试运行后也产生了gcda
文件。并且我们已经安装好lcov
,那么该如何使用lcov
来生成覆盖率报告呢?
-
进入到我们生成了
*.gcno
*.gcda
文件的目录
-
收集覆盖率数据(
*.gcda
)并写入文件
lcov -d . -c -o all.info --rc lcov_branch_coverage=1
Capturing coverage data from .
Found gcov version: 4.8.5
Scanning . for .gcda files …
Found 8 data files in .
Processing com.gcda
Processing device.gcda
Processing main.gcda
Processing model.gcda
Processing network.gcda
Processing test_model.gcda
Processing test_normal.gcda
Processing usb.gcda
Finished .info-file creation此时会在当前目录下生成一个
all.info
的文件,由上面命令执行过程输出的信息得知,其搜集了当前目录下所有gcda
文件的覆盖率数据。-d : 等同于
--directory
,指定目录, 指定的目录跟进-d
之后,用空格隔开。 这里使用了 . ,意味着当前目录
-c : 等同于--capture
,收集覆盖率数据
-o : 等同于--output-file
,表示输出到文件,文件名紧随其后,用空格隔开。这里使用了all.info
,表示收集到的数据输入到all.info
文件
–rc lcov_branch_coverage=1 : 开启分支覆盖率统计。lcov
从1.10
版本起,默认关闭分支覆盖率。可通过该参数开启
- 生成覆盖率报告
genhtml --branch-coverage -o result --rc lcov_branch_coverage=1 all.info // 从all.info文件中生成包含分支覆盖率的报告到result目录
Reading data file all.info
Found 74 entries.
Found common filename prefix “/mnt/hgfs/linuxShareFile/testDemo/utdemo”
Writing .css and .png files.
Generating output.
Processing file demo/model/model.cpp
Processing file demo/model/model.h
Processing file demo/model/device/device.cpp
Processing file demo/model/device/hardware/hardware.h
Processing file demo/model/device/hardware/com/com.cpp
Processing file demo/model/device/hardware/usb/usb.cpp
Processing file demo/model/network/network.cpp
Processing file demo/model/network/network.h
Processing file utdemo/qt/utdemo/utdemo/main.cpp
Processing file utdemo/src/gtest/cppfreemock/runtime_patch.h
Processing file utdemo/src/gtest/cppfreemock/cpp11/basic_type.h
Processing file utdemo/src/gtest/cppfreemock/cpp11/impl.h
Processing file utdemo/src/gtest/cppfreemock/posix/runtime_patch_impl.h
Processing file utdemo/src/gtest/cppfreemock/x86/runtime_patch_impl.h
Processing file utdemo/src/gtest/gmock/head/gmock/gmock-generated-function-mockers.h
Processing file utdemo/src/gtest/gmock/head/gmock/gmock-actions.h
Processing file utdemo/src/gtest/gmock/head/gmock/gmock-more-actions.h
Processing file utdemo/src/gtest/gmock/head/gmock/gmock-spec-builders.h
Processing file utdemo/src/gtest/gmock/head/gmock/gmock-generated-actions.h
Processing file utdemo/src/gtest/gmock/head/gmock/gmock-matchers.h
Processing file utdemo/src/gtest/gmock/head/gmock/gmock-cardinalities.h
Processing file utdemo/src/gtest/gmock/head/gmock/internal/gmock-internal-utils.h
Processing file utdemo/src/gtest/head/gtest/gtest.h
Processing file utdemo/src/gtest/head/gtest/gtest-printers.h
Processing file utdemo/src/gtest/head/gtest/gtest-test-part.h
Processing file utdemo/src/gtest/head/gtest/gtest-message.h
Processing file utdemo/src/gtest/head/gtest/internal/gtest-internal.h
Processing file utdemo/src/gtest/head/gtest/internal/gtest-param-util.h
Processing file utdemo/src/gtest/head/gtest/internal/gtest-port.h
Processing file utdemo/src/gtest/head/gtest/internal/gtest-linked_ptr.h
Processing file utdemo/src/gtest/head/gtest/internal/gtest-death-test-internal.h
Processing file utdemo/src/head/test_model.h
Processing file utdemo/src/head/test_normal.h
Processing file utdemo/src/test_src/test_normal.cpp
Processing file utdemo/src/test_src/test_model.cpp
Processing file /usr/include/bits/string3.h
Processing file /usr/include/bits/stdio2.h
Processing file /usr/include/c++/4.8.2/tuple
Processing file /usr/include/c++/4.8.2/ostream
Processing file /usr/include/c++/4.8.2/typeinfo
Processing file /usr/include/c++/4.8.2/initializer_list
Processing file /usr/include/c++/4.8.2/sstream
Processing file /usr/include/c++/4.8.2/functional
Processing file /usr/include/c++/4.8.2/streambuf
Processing file /usr/include/c++/4.8.2/iostream
Processing file /usr/include/c++/4.8.2/bits/stl_iterator_base_funcs.h
Processing file /usr/include/c++/4.8.2/bits/stl_set.h
Processing file /usr/include/c++/4.8.2/bits/stl_algobase.h
Processing file /usr/include/c++/4.8.2/bits/shared_ptr_base.h
Processing file /usr/include/c++/4.8.2/bits/hashtable_policy.h
Processing file /usr/include/c++/4.8.2/bits/stl_bvector.h
Processing file /usr/include/c++/4.8.2/bits/stl_pair.h
Processing file /usr/include/c++/4.8.2/bits/functional_hash.h
Processing file /usr/include/c++/4.8.2/bits/char_traits.h
Processing file /usr/include/c++/4.8.2/bits/stl_vector.h
Processing file /usr/include/c++/4.8.2/bits/unordered_map.h
Processing file /usr/include/c++/4.8.2/bits/stl_uninitialized.h
Processing file /usr/include/c++/4.8.2/bits/stl_list.h
Processing file /usr/include/c++/4.8.2/bits/stl_iterator.h
Processing file /usr/include/c++/4.8.2/bits/hashtable.h
Processing file /usr/include/c++/4.8.2/bits/alloc_traits.h
Processing file /usr/include/c++/4.8.2/bits/locale_facets.h
Processing file /usr/include/c++/4.8.2/bits/vector.tcc
Processing file /usr/include/c++/4.8.2/bits/basic_string.tcc
Processing file /usr/include/c++/4.8.2/bits/shared_ptr.h
Processing file /usr/include/c++/4.8.2/bits/move.h
Processing file /usr/include/c++/4.8.2/bits/stl_construct.h
Processing file /usr/include/c++/4.8.2/bits/basic_string.h
Processing file /usr/include/c++/4.8.2/bits/list.tcc
Processing file /usr/include/c++/4.8.2/bits/stl_tree.h
Processing file /usr/include/c++/4.8.2/ext/new_allocator.h
Processing file /usr/include/c++/4.8.2/ext/atomicity.h
Processing file /usr/include/c++/4.8.2/ext/concurrence.h
Processing file /usr/include/c++/4.8.2/ext/alloc_traits.h
Writing directory view page.
Overall coverage rate:
lines…: 52.3% (776 of 1485 lines)
functions…: 26.8% (186 of 694 functions)
branches…: 16.1% (362 of 2245 branches)–branch-coverage : 显式指定需要在报告中显示分支覆盖率,搭配后面的参数
--rc lcov_branch_coverage=1
使用。如果不需要,则需要使用参数--no-branch-coverage
显示指定不显示分支覆盖率。
-o : 等同于--output
,表示输出到目录,目录名紧随其后,用空格隔开。这里使用了result
,表示将报告输出到当前路径下的result
目录中
–rc lcov_branch_coverage=1 : 开启分支覆盖率统计。lcov
从1.10
版本起,默认关闭分支覆盖率。可通过该参数开启
- 查看报告
firefox result/index.html
firefox 和上面的 genhtml 都是lcov自带的工具,安装完lcov即可使用
成功生成了覆盖率报告!: P hoooooooo~等……等…………
怎么多了那么多usr
路径下的c++
相关的内容,还有gtest
框架目录也生产了报告?我们完全不需要这些,而且这还只是个demo
程序,如果真实项目,依赖更多,岂不是想要找个工程文件的覆盖率详情,还得滚个好几页?我们需要筛选出我们关注的内容,将系统相关的、我们不关注的内容给屏蔽掉。
- 筛选关注文件的覆盖率(过滤非关注[系统依赖/头文件/测试框架等]的覆盖率)
lcov -r all.info "*.h" -o all.info --rc lcov_branch_coverage=1 // 从all.info中移除头文件的所有内容
Reading tracefile all.info
Removing /mnt/hgfs/linuxShareFile/testDemo/utdemo/demo/model/device/hardware/hardware.h
Removing /mnt/hgfs/linuxShareFile/testDemo/utdemo/demo/model/model.h
Removing /mnt/hgfs/linuxShareFile/testDemo/utdemo/demo/model/network/network.h
Removing /mnt/hgfs/linuxShareFile/testDemo/utdemo/utdemo/src/gtest/cppfreemock/cpp11/basic_type.h
Removing /mnt/hgfs/linuxShareFile/testDemo/utdemo/utdemo/src/gtest/cppfreemock/cpp11/impl.h
Removing /mnt/hgfs/linuxShareFile/testDemo/utdemo/utdemo/src/gtest/cppfreemock/posix/runtime_patch_impl.h
Removing /mnt/hgfs/linuxShareFile/testDemo/utdemo/utdemo/src/gtest/cppfreemock/runtime_patch.h
Removing /mnt/hgfs/linuxShareFile/testDemo/utdemo/utdemo/src/gtest/cppfreemock/x86/runtime_patch_impl.h
Removing /mnt/hgfs/linuxShareFile/testDemo/utdemo/utdemo/src/gtest/gmock/head/gmock/gmock-actions.h
Removing /mnt/hgfs/linuxShareFile/testDemo/utdemo/utdemo/src/gtest/gmock/head/gmock/gmock-cardinalities.h
Removing /mnt/hgfs/linuxShareFile/testDemo/utdemo/utdemo/src/gtest/gmock/head/gmock/gmock-generated-actions.h
Removing /mnt/hgfs/linuxShareFile/testDemo/utdemo/utdemo/src/gtest/gmock/head/gmock/gmock-generated-function-mockers.h
Removing /mnt/hgfs/linuxShareFile/testDemo/utdemo/utdemo/src/gtest/gmock/head/gmock/gmock-matchers.h
Removing /mnt/hgfs/linuxShareFile/testDemo/utdemo/utdemo/src/gtest/gmock/head/gmock/gmock-more-actions.h
Removing /mnt/hgfs/linuxShareFile/testDemo/utdemo/utdemo/src/gtest/gmock/head/gmock/gmock-spec-builders.h
Removing /mnt/hgfs/linuxShareFile/testDemo/utdemo/utdemo/src/gtest/gmock/head/gmock/internal/gmock-internal-utils.h
Removing /mnt/hgfs/linuxShareFile/testDemo/utdemo/utdemo/src/gtest/head/gtest/gtest-message.h
Removing /mnt/hgfs/linuxShareFile/testDemo/utdemo/utdemo/src/gtest/head/gtest/gtest-printers.h
Removing /mnt/hgfs/linuxShareFile/testDemo/utdemo/utdemo/src/gtest/head/gtest/gtest-test-part.h
Removing /mnt/hgfs/linuxShareFile/testDemo/utdemo/utdemo/src/gtest/head/gtest/gtest.h
Removing /mnt/hgfs/linuxShareFile/testDemo/utdemo/utdemo/src/gtest/head/gtest/internal/gtest-death-test-internal.h
Removing /mnt/hgfs/linuxShareFile/testDemo/utdemo/utdemo/src/gtest/head/gtest/internal/gtest-internal.h
Removing /mnt/hgfs/linuxShareFile/testDemo/utdemo/utdemo/src/gtest/head/gtest/internal/gtest-linked_ptr.h
Removing /mnt/hgfs/linuxShareFile/testDemo/utdemo/utdemo/src/gtest/head/gtest/internal/gtest-param-util.h
Removing /mnt/hgfs/linuxShareFile/testDemo/utdemo/utdemo/src/gtest/head/gtest/internal/gtest-port.h
Removing /mnt/hgfs/linuxShareFile/testDemo/utdemo/utdemo/src/head/test_model.h
Removing /mnt/hgfs/linuxShareFile/testDemo/utdemo/utdemo/src/head/test_normal.h
Removing /usr/include/bits/stdio2.h
Removing /usr/include/bits/string3.h
Removing /usr/include/c++/4.8.2/bits/alloc_traits.h
Removing /usr/include/c++/4.8.2/bits/basic_string.h
Removing /usr/include/c++/4.8.2/bits/char_traits.h
Removing /usr/include/c++/4.8.2/bits/functional_hash.h
Removing /usr/include/c++/4.8.2/bits/hashtable.h
Removing /usr/include/c++/4.8.2/bits/hashtable_policy.h
Removing /usr/include/c++/4.8.2/bits/locale_facets.h
Removing /usr/include/c++/4.8.2/bits/move.h
Removing /usr/include/c++/4.8.2/bits/shared_ptr.h
Removing /usr/include/c++/4.8.2/bits/shared_ptr_base.h
Removing /usr/include/c++/4.8.2/bits/stl_algobase.h
Removing /usr/include/c++/4.8.2/bits/stl_bvector.h
Removing /usr/include/c++/4.8.2/bits/stl_construct.h
Removing /usr/include/c++/4.8.2/bits/stl_iterator.h
Removing /usr/include/c++/4.8.2/bits/stl_iterator_base_funcs.h
Removing /usr/include/c++/4.8.2/bits/stl_list.h
Removing /usr/include/c++/4.8.2/bits/stl_pair.h
Removing /usr/include/c++/4.8.2/bits/stl_set.h
Removing /usr/include/c++/4.8.2/bits/stl_tree.h
Removing /usr/include/c++/4.8.2/bits/stl_uninitialized.h
Removing /usr/include/c++/4.8.2/bits/stl_vector.h
Removing /usr/include/c++/4.8.2/bits/unordered_map.h
Removing /usr/include/c++/4.8.2/ext/alloc_traits.h
Removing /usr/include/c++/4.8.2/ext/atomicity.h
Removing /usr/include/c++/4.8.2/ext/concurrence.h
Removing /usr/include/c++/4.8.2/ext/new_allocator.h
Deleted 55 files
Writing data to all.info
Summary coverage rate:
lines…: 43.7% (162 of 371 lines)
functions…: 24.6% (34 of 138 functions)
branches…: 12.3% (80 of 649 branches)
lcov -r all.info "/gtest/" -o all.info --rc lcov_branch_coverage=1 // 从all.info中移除gtest目录下的所有内容
Reading tracefile all.info
Deleted 0 files
Writing data to all.info
Summary coverage rate:
lines…: 43.7% (162 of 371 lines)
functions…: 24.6% (34 of 138 functions)
branches…: 12.3% (80 of 649 branches)
lcov -r all.info "/usr/" -o all.info --rc lcov_branch_coverage=1 // 从all.info中移除usr目录下的所有内容
Reading tracefile all.info
Removing /usr/include/c++/4.8.2/bits/basic_string.tcc
Removing /usr/include/c++/4.8.2/bits/list.tcc
Removing /usr/include/c++/4.8.2/bits/vector.tcc
Removing /usr/include/c++/4.8.2/functional
Removing /usr/include/c++/4.8.2/initializer_list
Removing /usr/include/c++/4.8.2/iostream
Removing /usr/include/c++/4.8.2/ostream
Removing /usr/include/c++/4.8.2/sstream
Removing /usr/include/c++/4.8.2/streambuf
Removing /usr/include/c++/4.8.2/tuple
Removing /usr/include/c++/4.8.2/typeinfo
Deleted 11 files
Writing data to all.info
Summary coverage rate:
lines…: 28.2% (66 of 234 lines)
functions…: 18.2% (20 of 110 functions)
branches…: 12.2% (62 of 510 branches)
- 再次生成并查看筛选后的报告
genhtml --branch-coverage -o result --rc lcov_branch_coverage=1 all.info
Reading data file all.info
Found 8 entries.
Found common filename prefix “/mnt/hgfs/linuxShareFile/testDemo/utdemo”
Writing .css and .png files.
Generating output.
Processing file demo/model/model.cpp
Processing file demo/model/device/device.cpp
Processing file demo/model/device/hardware/com/com.cpp
Processing file demo/model/device/hardware/usb/usb.cpp
Processing file demo/model/network/network.cpp
Processing file utdemo/qt/utdemo/utdemo/main.cpp
Processing file utdemo/src/test_src/test_normal.cpp
Processing file utdemo/src/test_src/test_model.cpp
Writing directory view page.
Overall coverage rate:
lines…: 28.2% (66 of 234 lines)
functions…: 18.2% (20 of 110 functions)
branches…: 12.2% (62 of 510 branches)相比第一次生成报告时输出的记录少了很多。
firefox result/index.html // 查看报告↓↓↓
-
点击查看指定目录下文件的覆盖率概况
-
查看指定文件覆盖率详情
至此,我们已经成功的使用gcov
+ lcov
生成了代码覆盖率报告,我们可更有针对性的对未被覆盖的代码设计对应的单元测试进行测试验证,为健壮的代码添砖加瓦。
其实在本人所使用的RedflagX86_64
环境下,安装完lcov
第一次使用的时候,提示缺少 perl-Digest-MD5*
的错误:
Can’t locate Digest/MD5.pm in @INC (@INC contains: /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 .) at /usr/local/bin/geninfo line 58.
BEGIN failed–compilation aborted at /usr/local/bin/geninfo line 58.
遇到这种情况,需要先安装依赖项perl-Digest-1.17-.rpm
,再安装perl-Digest-MD5-.rpm
。
不巧的是使用的环境无法通过源直接安装,所以这里使用离线包进行安装:
$ sudo rpm -ivh perl-Digest-1.17-245.el7.noarch.rpm
[sudo] password for root:
警告:perl-Digest-1.17-245.el7.noarch.rpm: 头V3 RSA/SHA256 Signature, 密钥 ID f4a80eb5: NOKEY
准备中... ################################# [100%]
软件包 perl-Digest-1.17-245.el7.noarch 已经安装
$ sudo rpm -ivh perl-Digest-MD5-2.52-3.el7.x86_64.rpm
警告:perl-Digest-MD5-2.52-3.el7.x86_64.rpm: 头V3 RSA/SHA256 Signature, 密钥 ID f4a80eb5: NOKEY
准备中... ################################# [100%]
软件包 perl-Digest-MD5-2.52-3.el7.x86_64 已经安装
也可扫码关注博主同名公众号 “不解之榬” 查看