使用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.a17 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-testLIBRARY 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.info10 directories, 22 files

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

open index.html

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

公司面试题总结(三)

13.说说你对 BOM 的理解&#xff0c;常见的 BOM 对象你了解哪些&#xff1f; BOM (Browser Object Model)&#xff0c;浏览器对象模型&#xff0c; ⚫ 提供了独立于内容与浏览器窗口进行交互的对象 ⚫ 其作用就是跟浏览器做一些交互效果 ⚫ 比如如何进行页面的后退&…

VIRT高是因为分配了太多地址空间导致。

一般来说不用太在意VIRT太高&#xff0c;因为你有16EB的空间可以使用。 如果你实在需要控制VIRT的使用&#xff0c;设置环境变量MALLOC_ARENA_MAX&#xff0c;例如: hadoop推荐值为4&#xff0c;因为YARN使用VIRT值监控资源使用。 解决办法就是&#xff1a; export MALLOC_AR…

C语言中的枚举类型(enum)是如何定义的

在C语言中&#xff0c;枚举类型&#xff08;enum&#xff09;是一种用户定义的数据类型&#xff0c;它允许为整数值指定一个易读的名字。枚举类型通常用于表示固定数量的可能值&#xff0c;例如一周的七天或颜色的集合。 枚举类型的定义使用关键字 enum&#xff0c;后面跟着枚…

QUIC 和 TCP: 深入解析为什么 QUIC 更胜一筹

引言 在过去的三十年里&#xff0c;HTTP&#xff08;超文本传输协议&#xff09;一直是互联网的支柱。我们可以通过 HTTP 浏览网页、下载文件、流式传输电影等。这一协议随着时间的推移已经得到了重大改进。 HTTP 协议是一个应用层协议&#xff0c;它基于 TCP&#xff08;传输…

【git使用一】windows下git下载、安装和卸载

目录 &#xff08;1&#xff09;下载安装包 &#xff08;2&#xff09;安装git &#xff08;3&#xff09;安装验证 &#xff08;4&#xff09;卸载git &#xff08;1&#xff09;下载安装包 官网下载地址&#xff1a;Git 国内镜像下载地址&#xff1a;CNPM Binaries Mir…

Unity图集

概述 相信在同学们学习过程中&#xff0c;在UI的的使用时候一定经常听说过图集的概念。 Unity有UI的组件&#xff0c;有同学们好奇&#xff0c;那为什么还要使用图集呢&#xff1f; 这就需要提到一个性能优化的问题了&#xff0c;因为过多的UI图片&#xff0c;会大幅增加Dra…

【机器学习】LightGBM: 优化机器学习的高效梯度提升决策树

&#x1f308;个人主页: 鑫宝Code &#x1f525;热门专栏: 闲话杂谈&#xff5c; 炫酷HTML | JavaScript基础 ​&#x1f4ab;个人格言: "如无必要&#xff0c;勿增实体" 文章目录 LightGBM: 优化机器学习的高效梯度提升决策树引言一、LightGBM概览二、核心技术…

buildroot编译出错you should not run configure as root

虚拟机版本&#xff1a;ubuntu-22.04.4 问题 buildroot在图形配置后&#xff0c;执行 sudo make开始编译出现以下错误configure: error: you should not run configure as root (set FOenvironment to bypass this check) 在网上看到说在/etc/profile文件中添加以下内容 exp…

火车头采集织梦发布模块插件下载及教程

火车头采集网页数据发布到织梦CMS&#xff08;DeDeCMS&#xff09;系统操作步骤如下&#xff1a; 1. 火车头采集织梦DeDeCMS发布模块下载安装 百度网盘&#xff1a;火车头采集织梦CMS发布插件下载地址 提取码&#xff1a;414h 2. 在火车头采集软件导入织梦De…

MAC系统下安装VUE

下载node.js 点击链接 选择图片中的稳定版本 安装node.js 打开终端&#xff0c;输入 node -v 和 npm -v 显示如上信息表示安装成功 安装vue脚手架&#x1f527; sudo npm install -g vue/cli查看vue版本 vue -V6. 启动项目 1 采用 图形页面方式 控制台输入&#xff…

MySQL 中 Varchar(50) 和 varchar(500) 区别是什么?

一. 问题描述 我们在设计表结构的时候&#xff0c;设计规范里面有一条如下规则: 对于可变长度的字段&#xff0c;在满足条件的前提下&#xff0c;尽可能使用较短的变长字段长度。 为什么这么规定&#xff1f;我在网上查了一下&#xff0c;主要基于两个方面 基于存储空间的考…

C# Winform 用户控件,扩展控件,自定义控件综合实例

Control类是Windows窗体控件的基类&#xff0c;它提供了在 Windows 窗体应用程序中进行可视显示所需的基础结构&#xff0c;可以通过继承来扩展熟悉的用户控件和现有控件的功能。本列介绍三种不同自定义控件以及怎么创建他们。 自定义控件分类 用户控件&#xff1a;基本控件的…

IT入门知识博客文章大纲第二部分《编程语言》(2/10)

目录 IT入门知识博客文章大纲第二部分《编程语言》 1.引言 2.编程语言概述 2.1 编程语言的发展历程 2.2 编程范式 3.常见的编程语言 3.1 Python 3.2 Java 3.3 C 3.4 JavaScript 3.5 Ruby 4.编程语言的选择 4.1 技术需求 4.2 团队技能 4.3 社区和生态系统 4.4 可…

Python也能“零延迟“通信吗?ZeroMQ带你开启高速模式!

目录 1、零基础入门ZeroMQ 🚀 1.1 ZeroMQ简介与安装 1.2 基础概念:Socket类型详解 1.3 实战演练:Hello World示例 2、深入浅出消息模式 🔌 2.1 请求-应答模式( REQ/REP ) 2.2 发布-订阅模式( PUB/SUB ) 2.3 推送-拉取模式( PUSH/PULL ) 3、Python实战ZeroM…

Aptos Builder Jam 亚洲首站|议程公布,无限畅想 Aptos 生态未来

作为一个新兴的 Layer1 公链&#xff0c;Aptos 自诞生之日起的理想便是 “A Layer 1 for everyone” 当 Web3 深陷熊市阴影之时&#xff0c;Aptos 奋力为开发者找到了全新的技术路径&#xff0c;正有 200 项目正在开发&#xff0c;并且已有大量 DeFi 项目落实部署工作&#xff…

C语言实现卡尔曼滤波器(Kalman Filter)

C语言实现卡尔曼滤波器(Kalman Filter) 理论知识参考卡尔曼滤波器 C语言实现 //KalmanFilter 结构体定义了卡尔曼滤波器的参数和状态变量。 //kalman_init 函数用于初始化卡尔曼滤波器的参数。 //kalman_update 函数实现了卡尔曼滤波器的预测和更新步骤。 //main 函数演示了…

AWS无服务器 应用程序开发—第十一章API Gateway

API Gateway 是 AWS 提供的一种托管服务,用于创建、发布、维护、保护和监控 RESTful 和 WebSocket API。它可以帮助开发者构建可扩展的微服务架构,并提供了丰富的功能来管理 API 的生命周期和流量。 主要功能和特点: API 创建和管理: 可以使用 API Gateway 快速创建和定…

shell文本三剑客 awk 和 grep

awk 前言 AWK是一种优良的文本处理工具。它不仅是 Linux中也是任何环境中现有的功能最强大的数据处理引擎之一。 Linux中最常用的文本处理工具有grep&#xff0c;sed&#xff0c;awk。行内将之称为文本三剑客&#xff0c;就功能量和效率来看&#xff0c;awk是当之无愧的文本三…

强化学习-tutorial

强化学习 当你发现收集有标注的数据困难&#xff0c;正确答案人类也不知道是什么的时候&#xff0c;往往是考虑使用RL的时候。尽管机器不知道答案是什么&#xff0c;但是机器会知道什么好&#xff0c;什么不好&#xff0c;通过与环境互动获得奖励。 过程 演算法解RL问题&…

常用的工具:pdf转换器、流程图

好用的&#xff08;大概率找的免费的&#xff09;常用的工具&#xff1a; pdf转换器/文件转换&#xff1a; 转换器1转换器2-TextIn转换器 流程图/思维导图&#xff1a; 墨刀GitMind