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

前言

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

准备工作

编译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

安装lcov

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

brew install lcov

跑demo

建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

编写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();
}

运行

代码覆盖率

    在上图的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

相关推荐

  1. gtest 单元测试

    2024-06-15 16:52:03       30 阅读
  2. 软件测试:C++ Google Test单元测试框架GTest

    2024-06-15 16:52:03       20 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-06-15 16:52:03       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-06-15 16:52:03       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-06-15 16:52:03       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-06-15 16:52:03       18 阅读

热门阅读

  1. 观察者模式

    2024-06-15 16:52:03       8 阅读
  2. WebSocket定时前端推送:深度解析与实战挑战

    2024-06-15 16:52:03       6 阅读
  3. ReentrantReadWriteLock:深度解析与源码探险

    2024-06-15 16:52:03       7 阅读
  4. 课时156:脚本发布_简单脚本_变量转化

    2024-06-15 16:52:03       12 阅读
  5. 面试题分享--Spring02

    2024-06-15 16:52:03       9 阅读