0


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

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 建qt工程

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

进入到demo的工程根目录,将googletest编译安装之后的**include**和**lib**文件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.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.3 运行

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

标签: 单元测试

本文转载自: https://blog.csdn.net/weixin_41255248/article/details/139702332
版权归原作者 老中医的博客 所有, 如有侵权,请联系我们删除。

“使用gtest做cpp的单元测试并查看代码覆盖率”的评论:

还没有评论