当前位置: 代码网 > it编程>编程语言>Java > 使用gtest做cpp的单元测试并查看代码覆盖率

使用gtest做cpp的单元测试并查看代码覆盖率

2024年08月01日 Java 我要评论
由于工作需要,要使用googletest做单元测试,本文记录下搭建gtest单元测试环境,并查看代码覆盖率的方法,以备不时之需。

 1 前言

    由于工作需要,要使用googletest做单元测试,本文记录下搭建gtest单元测试环境,并查看代码覆盖率的方法,以备不时之需。

2 准备工作

2.1 编译gtest

克隆gtest源码:

git clone https://github.com/google/googletest.git

    使用缺省分支main,并在googletest源码当前目录创建一个编译的build目录:

mkdir -p build && cd build

     进入到build目录下,执行如下命令:

cmake .. && make -j9 && make install destdir=./

     编译安装完成,gtest相关头文件在以下目录,其中lib和usr目录在googletest根目录:

├── lib
│   ├── libgmock.a
│   ├── libgmock_main.a
│   ├── libgtest.a
│   └── libgtest_main.a
└── usr
    └── local
        ├── include
        │   ├── gmock
        │   └── gtest
        └── lib
            ├── cmake
            ├── libgmock.a
            ├── libgmock_main.a
            ├── libgtest.a
            ├── libgtest_main.a
            └── pkgconfig

2.2 安装lcov

    macos下需要使用lcov来生成单元测试的覆盖率报告,用brew下载即可:

brew install lcov

3 跑demo

3.1 cmake构建

3.1.1 建qt工程

    至此, 万事俱备,现在使用qt创建一个c++的工程:

    进入到demo的工程根目录,将googletest编译安装之后的includelib文件copy至demo的当前根目录下,注意gtest目录下便是依赖文件:

mingo@localhost:~/applications/workspace/tools/unit_test$tree -l 3
.
├── build-cpp-unit-test-desktop_arm_darwin_generic_mach_o_64bit-debug
│   ├── cmakecache.txt
│   ├── cmakecache.txt.prev
│   ├── cmakefiles
│   │   ├── 3.26.0
│   │   ├── cmakeconfigurelog.yaml
│   │   ├── targetdirectories.txt
│   │   ├── cmake.check_cache
│   │   ├── cpp-unit-test.dir
│   │   ├── pkgredirects
│   │   └── rules.ninja
│   ├── testing
│   │   └── temporary
│   ├── build.ninja
│   ├── cmake_install.cmake
│   ├── cpp-unit-test
│   ├── output
│   │   ├── users
│   │   ├── amber.png
│   │   ├── cmd_line
│   │   ├── emerald.png
│   │   ├── gcov.css
│   │   ├── glass.png
│   │   ├── index-sort-f.html
│   │   ├── index-sort-l.html
│   │   ├── index.html
│   │   ├── ruby.png
│   │   ├── snow.png
│   │   ├── updown.png
│   │   └── v1
│   ├── qtcsettings.cmake
│   └── test.info
├── cpp-unit-test
│   ├── cmakelists.txt
│   ├── cmakelists.txt.user
│   └── main.cpp
└── gtest
    ├── include
    │   ├── gmock
    │   └── gtest
    └── lib
        ├── libgmock.a
        ├── libgmock_main.a
        ├── libgtest.a
        └── libgtest_main.a

17 directories, 29 files

3.1.2 编写cmakelists 

    然后编写cmakelists构建脚本:

cmake_minimum_required(version 3.5)

project(cpp-unit-test languages cxx)

set(cmake_cxx_standard 17)
set(cmake_cxx_standard_required on)

# lcov相关编译选项
#set(gcc_coverage_compile_flags "-g -o0 -coverage -fprofile-arcs -ftest-coverage")
set(gcc_coverage_compile_flags "-g -o0 -fprofile-arcs -ftest-coverage")
#set(gcc_coverage_link_flags "-coverage -lcov")
#set(gcc_coverage_link_flags "-coverage")
set(cmake_cxx_flags "${cmake_cxx_flags} ${gcc_coverage_compile_flags}")
set(cmake_exe_linker_flags "${cmake_exe_linker_flags} ${gcc_coverage_link_flags}")

set(gtest_root_dir ${project_source_dir}/../gtest)
set(gtest_include_dir ${gtest_root_dir}/include)
set(gtest_lib_dir ${gtest_root_dir}/lib)
message("dir=${project_source_dir}")

include_directories(${gtest_include_dir})
#link_libraries(${gtest_lib_dir})
set(gtest_libs ${gtest_lib_dir}/libgtest.a ${gtest_lib_dir}/libgtest_main.a ${gtest_lib_dir}/libgmock.a ${gtest_lib_dir}/libgmock_main.a)

#target_link_libraries(cpp-unit-test gcov)
add_executable(cpp-unit-test main.cpp)
target_link_libraries(cpp-unit-test private ${gtest_libs})

install(targets cpp-unit-test
    library destination ${cmake_install_libdir})

     写一个最简单的测试用例:

#include <iostream>

using namespace std;

#include "gtest/gtest.h"
#include "gmock/gmock.h"

test(mytest, mytest1) {
    expect_true(1);
}

int main()
{
    cout << "hello world!" << endl;
    return run_all_tests();
}

3.1.3 运行

 3.1.4 代码覆盖率

    在上图的qt工程命令行里,可以看到用例的通过数和失败数,但还不够直观,此处使用lcov来生成html网页形式查看代码覆盖率

    进入到demo的构建目录下:

mingo@localhost:~/applications/workspace/tools/unit_test/build-cpp-unit-test-desktop_arm_darwin_generic_mach_o_64bit-debug$ll
total 3352
drwxr-xr-x  16 mingo  staff      512  6 15 14:29 ./
drwxr-xr-x   5 mingo  staff      160  6 15 13:30 ../
drwxr-xr-x   3 mingo  staff       96  6 15 13:30 .cmake/
-rw-r--r--   1 mingo  staff   149532  6 15 14:26 .ninja_deps
-rw-r--r--   1 mingo  staff      383  6 15 14:26 .ninja_log
drwxr-xr-x   4 mingo  staff      128  6 15 13:30 .qtc_clangd/
-rw-r--r--   1 mingo  staff    13148  6 15 13:30 cmakecache.txt
-rw-r--r--   1 mingo  staff    13148  6 15 13:30 cmakecache.txt.prev
drwxr-xr-x   9 mingo  staff      288  6 15 14:26 cmakefiles/
drwxr-xr-x   3 mingo  staff       96  6 15 13:30 testing/
-rw-r--r--   1 mingo  staff    11042  6 15 14:26 build.ninja
-rw-r--r--   1 mingo  staff     2238  6 15 13:30 cmake_install.cmake
-rwxr-xr-x   1 mingo  staff  1416352  6 15 14:26 cpp-unit-test*
drwxr-xr-x  15 mingo  staff      480  6 15 14:29 output/
-rw-r--r--   1 mingo  staff       52  6 15 14:26 qtcsettings.cmake
-rw-r--r--   1 mingo  staff    25803  6 15 14:28 test.info

    然后执行如下命令: 

lcov -c -o test.info -d .

    报了如下错:

geninfo: error: (inconsistent) "gtest-internal.h":454: function _zn7testing8internal15testfactoryimpli19mytest_mytest1_testec1ev end line 444 less than start line 454.  cannot derive function end line.  see lcovrc man entry for 'derive_function_end_line'.
	(use "geninfo --ignore-errors inconsistent ..." to bypass this error)

     解决办法:

lcov -c -o test.info -d . --ignore-errors inconsistent

    可以看到,执行成功之后,会在当前目录下生成test.info文件: 

test.info

    然后,在当前目录下创建output目录,用来存放覆盖率报告相关的html文件: 

mkdir -p output && genhtml test.info -o ./output --ignore-errors inconsistent

    以上命令执行成功,会在如下output目录下产生html相关的文件: 

mingo@localhost:~/applications/workspace/tools/unit_test/build-cpp-unit-test-desktop_arm_darwin_generic_mach_o_64bit-debug$tree -l 2
.
├── cmakecache.txt
├── cmakecache.txt.prev
├── cmakefiles
│   ├── 3.26.0
│   ├── cmakeconfigurelog.yaml
│   ├── targetdirectories.txt
│   ├── cmake.check_cache
│   ├── cpp-unit-test.dir
│   ├── pkgredirects
│   └── rules.ninja
├── testing
│   └── temporary
├── build.ninja
├── cmake_install.cmake
├── cpp-unit-test
├── output
│   ├── users
│   ├── amber.png
│   ├── cmd_line
│   ├── emerald.png
│   ├── gcov.css
│   ├── glass.png
│   ├── index-sort-f.html
│   ├── index-sort-l.html
│   ├── index.html
│   ├── ruby.png
│   ├── snow.png
│   ├── updown.png
│   └── v1
├── qtcsettings.cmake
└── test.info

10 directories, 22 files

     进入到output目录下,执行如下命令:

open index.html

3.2 xcode构建

3.2.1 安装工具

    用brew工具安装以下2个llvm相关的工具:

brew install llvm
brew install llvm-cov

    并将安装目录bin配置到path环境变量中去。,然后执行以下命令生效:

source ~/.bash_profile

3.2.2 环境搭建

    首先,用xcode创建一个纯c++的target工程,如下:

    并增加编译选项:

 在target的build settings => apple clang-custom compiler flags => other c flags / other c++ flags 2栏增加以下2个编译选项:

-fprofile-instr-generate
-fcoverage-mapping

   并在build settings => build options => enable code coverage support => yes

   在build phases => link binary with libraries 增加llvm覆盖率的库文件

libclang_rt.profile_osx.a

    m1芯片下,此库在llvm安装后生成在以下目录:

/applications/xcode.app/contents/developer/toolchains/xcodedefault.xctoolchain/usr/lib/clang/15.0.0/lib/darwin/

3.2.3 代码覆盖率

    运行xcode程序后,到可执行文件所在目录执行

./video_cache_unittest

    而后会生成default.profraw文件 

xcrun llvm-cov show ./video_cache_unittest -instr-profile=default.profdata -format=html -output-dir=coverage_report

    找到生成的 .profraw 文件,合并它们生成 .profdata 文件: 

xcrun llvm-profdata merge -sparse default.profraw -o default.profdata

   使用 llvm-cov 工具生成 html 报告:

xcrun llvm-cov show ./video_cache_unittest -instr-profile=default.profdata -format=html -output-dir=coverage_report

    最后生成的覆盖率目录结构大致如下: 

mingo@localhost:~/library/developer/xcode/deriveddata/video_cache_proxy-dtlzrjkxnibrjmeyqwheuwsphlau/build/products/debug$tree -l 3
.
├── coverage_report
│   ├── coverage
│   │   └── users
│   ├── index.html
│   └── style.css
├── coverage_report.txt
├── default.profdata
├── default.profraw
├── errorlog
├── libvideo_cache.a
├── video_cache_unittest
└── xactlog

    再进入到coverage_report目录下,执行以下命令:

open index.html

    就可以看到单元测试的覆盖率报告了: 

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com