使用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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/712437.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Vue44-创建vue脚手架

一、Vue脚手架的版本说明 vue cli&#xff1a;command line interface 命令行接口工具 用最新的脚手架&#xff0c;这样可以兼容vue3荷vue2版本。 二、通过vue脚手架创建项目 注意&#xff1a; 执行npm run serve 启动项目的时候&#xff0c;要进入到创建的vue项目里面&…

Java高级特性

引言 Java不仅提供了基础的编程功能&#xff0c;还包括了一系列强大的高级特性&#xff0c;这些特性能够显著提高代码的灵活性、可扩展性和性能。本文将详细介绍Java的几个高级特性&#xff0c;包括反射机制、注解与注释、泛型编程、以及Lambda表达式与Stream API&#xff0c;并…

KVM+GFS分布式存储系统构建高可用群集

KVMGFS 分布式存储系统构建 KVM 高可用群集 一&#xff1a;理论概述 1.1&#xff1a;Glusterfs 简介 Glusterfs 文件系统是由 Gluster 公司的创始人兼首席技术官 Anand Babu Periasamy编写。 一个可扩展的分布式文件系统&#xff0c; 用于大型的、 分布式的、 对大量数据进行访…

CrossOver 2024软件安装包下载

CrossOver不像Parallels或VMware的模拟器&#xff0c;而是实实在在Mac OS X系统上运行的一个软件。CrossOvers能够直接在Mac上运行Windows软件与游戏&#xff0c;而不需虚拟机。它为Windows软件提供所需的资源&#xff0c;以达到在Mac OS X系统上运行Windows程序的目的。 安 装…

OpenCV形态学

什么事形态学处理 基于图像形态进行处理的一些基本方法&#xff1b; 这些处理方法基本是对二进制图像进行处理&#xff1b; 卷积核决定着图像出来后的效果。 一 图像二值化 什么是二值化 将图像的每个像素变成两种值&#xff0c;如0,255. 全局二值化。 局部二值化。 thres…

【AIGC】MetaGPT原理以及应用

目录 MetaGPT原理 MetaGPT应用 MetaGPT和传统编程语言相比有什么优势和劣势 视频中的PPT 参考资料 MetaGPT原理 MetaGPT是一种多智能体框架&#xff0c;它结合了元编程技术&#xff0c;通过标准化操作程序&#xff08;SOPs&#xff09;来协调基于大语言模型的多智能体系统…

商品搬家到抖店

使用的工具为 张飞搬家&#xff0c;登录上去 张飞搬家 1 复制商品的网址 商品链接复制过去后&#xff0c;点击下面的开始批量复制 2 检查修改商品信息 价格啊、图片啊、各种商品属性啊&#xff0c;检查下&#xff0c;不合适的修改和补充 3 开始搬家 4 查看商品 打开抖店后…

数据库基础(一)

目录 一、一些基本概念 1. 四个事务隔离级别 Read Uncommitted&#xff08;读取未提交内容&#xff09; Read Committed&#xff08;读取提交内容&#xff09; Repeatable Read&#xff08;可重读&#xff09; Serializable&#xff08;可串行化&#xff09; 2. MVCC&am…

Windows运维:找到指定端口的服务

运维过windows的或多或少都遇到过需要找到一个端口对应的服务&#xff0c;或者是因为端口占用&#xff0c;或者是想看下对应的服务是哪个&#xff0c;那么如何操作呢&#xff1f;看看本文吧。 1、按照端口找到进程ID 例如想找8000端口的进程ID netstat -ano | findstr :8000 2…

大模型算法备案全网最详细说明(附附件)

本文要点&#xff1a;大模型备案最详细说明&#xff0c;大模型备案条件有哪些&#xff0c;《算法安全自评估报告》模板&#xff0c;大模型算法备案&#xff0c;大模型上线备案&#xff0c;生成式人工智能(大语言模型)安全评估要点&#xff0c;网信办大模型备案。 共分为以下几…

【Numpy】一文向您详细介绍 np.floor()

【Numpy】一文向您详细介绍 np.floor() 下滑即可查看博客内容 &#x1f308; 欢迎莅临我的个人主页 &#x1f448;这里是我静心耕耘深度学习领域、真诚分享知识与智慧的小天地&#xff01;&#x1f387; &#x1f393; 博主简介&#xff1a;985高校的普通本硕&#xff0c;…

【操作与配置】Pytorch环境搭建

安装显卡驱动 显卡驱动是一种软件程序&#xff0c;用于控制显卡硬件与操作系统之间的通信和交互。显卡驱动负责向操作系统提供有关显卡硬件的信息&#xff0c;以及使操作系统能够正确地控制和管理显卡的各种功能和性能。显卡驱动还包含了针对不同应用程序和游戏的优化&#xff…

python生成验证码图片,结合接口供前端调用

&#x1f308;所属专栏&#xff1a;【python】✨作者主页&#xff1a; Mr.Zwq✔️个人简介&#xff1a;一个正在努力学技术的Python领域创作者&#xff0c;擅长爬虫&#xff0c;逆向&#xff0c;全栈方向&#xff0c;专注基础和实战分享&#xff0c;欢迎咨询&#xff01; 您的…

海外仓系统如何让海外仓受益,WMS海外仓系统使用指南

随着跨境电商业务的快速发展&#xff0c;海外仓面临着需要更加高速运转的巨大挑战。 当海外仓出现因为手动作业导致效率低下&#xff0c;成本不断飙升或者出现库存管理问题的时候&#xff0c;意味着是时候引入一套合适的海外仓管理系统了。 对于寻求海外仓业务流程优化的企业…

2779. 数组的最大美丽值

简单翻译一下题目意思&#xff1a; 对于每个 nums[i] 都可以被替换成 [nums[i]-k, nums[i]k] 区间中的任何数&#xff0c;区间左右是闭的。在每个数字可以替换的前提下&#xff0c;返回数组中最多的重复数字的数量。 第一想法是用一个哈希表&#xff0c;Key 是可以被替换的数…

设置SSHkeys多服务器免登录配置(ssh config)

一、背景&#xff1a; 多邮箱或者多git账号进行同一台电脑开发的情况。 有时候&#xff0c;开发时可能会面临一个情况&#xff0c;就是通过自己的电脑&#xff0c;可能同时需要开发多个不同地方的项目&#xff0c;或者说&#xff0c;自己建立的项目已经配置好SSH验证免密登录&a…

阿里云系列产品免费用,不香吗?

阿里云系列产品免费用&#xff0c;不香吗&#xff1f; 什么是无影云电脑开启无影云下载安装客户端登录无影云桌面应用场景 开篇先发布一下阿里云产品免费体验地址&#xff1a;https://free.aliyun.com/?utm_contentg_1000370296 下面开始我的无影云电脑或者叫做无影云桌面的体…

【scikit-learn入门指南】:机器学习从零开始

1. 简介 scikit-learn是一款用于数据挖掘和数据分析的简单高效的工具&#xff0c;基于NumPy、SciPy和Matplotlib构建。它能够进行各种机器学习任务&#xff0c;如分类、回归和聚类。 2. 安装scikit-learn 在开始使用scikit-learn之前&#xff0c;需要确保已经安装了scikit-le…

【会议征稿,IEEE出版】第六届物联网、自动化和人工智能国际学术会议(IoTAAI 2024,7月26-28)

第六届物联网、自动化和人工智能国际会议&#xff08;IoTAAI 2024&#xff09;将于2024年07月26-28日在中国广州召开。 会议旨在拓展国际科技学术交流渠道&#xff0c;搭建学术资源共享平台&#xff0c;促进全球范围内的科技创新&#xff0c;提升中外学术合作。会议还鼓励不同领…

免费的端口映射工具哪个好用

端口映射&#xff0c;即从一个网络环境下的端口映射到另一个网络环境下访问的过程。通常由软件方式来提供这一过程的实现&#xff0c;或一些客户端工具。当涉及内外网时&#xff0c;如内网端口地址映射到外网地址&#xff0c;即是内网穿透的原理。免费的端口映射工具有哪些&…