当前位置: 首页 > news >正文

【可测试性实践】C++ 单元测试代码覆盖率统计入门

引言

最近在调研C++工程怎么做单元测试和代码覆盖率统计,由于我们工程有使用Boost库,尝试使用Boost.Test来实现单元测试并通过Gcov和Lcov来生成代码覆盖率报告。本文记录完整的搭建测试Demo,希望能带来一定参考。

常用C++单测框架对比

特性Google Test (gtest)Catch2Boost.TestCppUnit
开发者GooglePhil NashBoost社区CppUnit社区
许可证BSD 3-ClauseBoost Software LicenseBoost Software LicenseLGPL
平台支持跨平台跨平台跨平台跨平台
集成易于和CMake集成易于和CMake集成易于和CMake集成需要手动集成
断言风格宏定义 (ASSERT_*)宏定义 (REQUIRE, CHECK)宏定义 (BOOST_*)宏定义 (CPPUNIT_*)
测试发现自动自动自动手动
Mock支持需要第三方库需要第三方库需要第三方库需要第三方库
文档丰富的官方文档丰富的官方文档丰富的官方文档较少
社区支持强大活跃强大较少
扩展性较低
学习曲线平缓平缓较陡较陡
主要特点高性能, 多线程支持简洁, 可读性强功能强大, 但复杂基础功能

详细说明

  1. Google Test (gtest):
    • 优点: 强大的社区支持,丰富的文档,高性能,支持多线程测试。
    • 缺点: Mock功能需要额外的库(如Google Mock)。
  2. Catch2:
    • 优点: 代码简洁,测试代码可读性强,单头文件,集成方便。
    • 缺点: Mock功能需要额外的库。
  3. Boost.Test:
    • 优点: 功能强大,丰富的断言和测试功能,兼容Boost库。
    • 缺点: 学习曲线较陡,文档虽然丰富但略显复杂。
  4. CppUnit:
    • 优点: 基础功能稳定,适合老项目。
    • 缺点: 社区支持较少,文档不丰富,集成和扩展性较差。

使用Boost.Test框架实现单元测试

假设你工程使用是Boost库,可以通过Boost.Test来实现单元测试。

步骤一:安装 Boost 库

如果你还没有安装 Boost 库,可以按照以下步骤进行安装:

在 Linux 上(例如 Ubuntu)
sudo apt-get update
sudo apt-get install libboost-all-dev
在 Windows 上

你可以从 Boost 官方网站下载并安装 Boost 库。

在 Mac 上

可以通过 Homebrew 安装 Boost库:

brew install boost

步骤二:创建项目结构

示例工程结构:

/boost.test/srcadd.cppadd.hmain.cpp/testtest_add.cppCMakeLists.txt

步骤三:编写 CMakeLists.txt

在项目根目录下创建或编辑 CMakeLists.txt 文件:

cmake_minimum_required(VERSION 3.10)
project(boost.test)# 设置 C++ 标准
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED True)# 查找 Boost 库
find_package(Boost REQUIRED COMPONENTS unit_test_framework)if(Boost_FOUND)include_directories(${Boost_INCLUDE_DIRS})link_directories(${Boost_LIBRARY_DIRS})
else()message(FATAL_ERROR "Could not find Boost")
endif()# 添加编译选项以支持代码覆盖率
if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID)set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage")set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fprofile-arcs -ftest-coverage")set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} -fprofile-arcs -ftest-coverage -lgcov")message(STATUS "CMAKE_CXX_FLAGS: ${CMAKE_CXX_FLAGS}")message(STATUS "CMAKE_EXE_LINKER_FLAGS: ${CMAKE_EXE_LINKER_FLAGS}")
endif()# 包含 src 目录,以便找到 add.h
include_directories(${CMAKE_SOURCE_DIR}/src)# 添加源文件
add_executable(boost.test src/main.cpp src/add.cpp)# 添加测试可执行文件
add_executable(test_main test/test_add.cpp src/add.cpp)
target_link_libraries(test_main Boost::unit_test_framework)

步骤四:编写源文件

src/add.h中添加以下代码:

#ifndef ADD_H
#define ADD_Hint add(int a, int b);#endif // ADD_H

src/add.cpp中添加以下代码:

#include "add.h"int add(int a, int b) {return a + b;
}

src/main.cpp 中添加以下代码:

#include <iostream>int add(int a, int b) {return a + b;
}int main() {std::cout << "2 + 3 = " << add(2, 3) << std::endl;return 0;
}

步骤五:编写测试文件

test/test_add.cpp 中添加以下代码:

#define BOOST_TEST_MODULE test_main
#include <boost/test/included/unit_test.hpp>
#include "add.h"BOOST_AUTO_TEST_CASE(test_add) {BOOST_CHECK(add(2, 3) == 5);BOOST_CHECK(add(0, 0) == 0);BOOST_CHECK(add(-1, -1) == -2);
}

步骤六:构建和运行测试

在项目根目录下打开终端或命令提示符,并执行以下命令:

# 创建构建目录
mkdir build
cd build# 生成构建文件并编译项目
cmake ..
make# 运行测试
./test_main

你应该会看到类似于以下的输出,表示测试通过:

Running 1 test case...
*** No errors detected

详细说明

  • CMakeLists.txt:
    • find_package(Boost REQUIRED COMPONENTS unit_test_framework) 用来查找 Boost 库。
    • add_executable(test_main test/test_main.cpp src/add.cpp) 用来添加测试可执行文件。
    • target_link_libraries(test_main Boost::unit_test_framework) 用来链接 Boost.Test 库。
    • 添加 -fprofile-arcs</font>-ftest-coverage</font> 编译选项,以启用代码覆盖率信息的生成。
  • 测试代码:
    • #define BOOST_TEST_MODULE MyTest 定义测试模块名称。
    • #include <boost/test/included/unit_test.hpp> 包含 Boost.Test 的头文件。
    • BOOST_AUTO_TEST_CASE(test_add) 定义一个测试用例。

使用gcov + lcov统计代码覆盖率

准备工作

确保已经安装以下工具:

  • CMake:用于构建项目。
  • GCC:支持代码覆盖率生成(其他编译器如 Clang 也可以,但这里以 GCC 为例)。
  • gcov:GCC 自带的代码覆盖率工具。
  • lcov:用于生成 HTML 格式的覆盖率报告。
  • genhtml:用于将 lcov 生成的覆盖率数据转换为 HTML 文件。

GCOV 代码覆盖率统计流程

画板

由于gcov生成的代码覆盖率统计文件可视化较低,所以需要借助lcov,genhtml工具直接生成html报告。

生成覆盖率报告

# 生成初始的覆盖率信息
lcov --capture --directory . --output-file coverage.info# 过滤掉不需要的文件(如系统库和测试框架)
lcov --remove coverage.info '/usr/*' --output-file coverage.info
lcov --remove coverage.info '*/test/*' --output-file coverage.info# 生成 HTML 报告
genhtml coverage.info --output-directory out

查看覆盖率报告

代码覆盖率总览

add.cpp代码覆盖率统计

main.cpp代码覆盖率统计

遇到问题

笔者的开发环境主要是Mac+VSCode,但Lcov对Mac系统并不太友好,前面的demo工程虽然编译通过了,但生成代码覆盖率报告就报错,猜测Mac的符号表机制跟Linux不太一样,最后还是在私有构建机的Linux环境跑通了。

附录

  • https://github.com/google/googletest
  • https://github.com/catchorg/Catch2
  • https://www.boost.org/doc/libs/1_86_0/libs/test/doc/html/index.html
  • https://cppunit.github.io/cppunit/
  • https://github.com/linux-test-project/lcov
  • https://blog.csdn.net/qq_32534441/article/details/90645316

相关文章:

【可测试性实践】C++ 单元测试代码覆盖率统计入门

引言 最近在调研C工程怎么做单元测试和代码覆盖率统计&#xff0c;由于我们工程有使用Boost库&#xff0c;尝试使用Boost.Test来实现单元测试并通过Gcov和Lcov来生成代码覆盖率报告。本文记录完整的搭建测试Demo&#xff0c;希望能带来一定参考。 常用C单测框架对比 特性Goo…...

C++笔记---list

1. list的介绍 list其实就是就是我们所熟知的链表&#xff08;双向循环带头结点&#xff09;&#xff0c;但其是作为STL中的一个类模板而存在。 也就是说&#xff0c;list是可以用来存储任意类型数据的顺序表&#xff0c;既可以是内置类型&#xff0c;也可以是自定义类型&…...

JavaWeb开发中为什么Controller里面的方法是@RequestMapping?

在Java Web开发中&#xff0c;尤其是在使用Spring MVC框架时&#xff0c;RequestMapping注解被广泛应用于Controller层的方法上&#xff0c;这是因为RequestMapping是Spring MVC提供的一个核心注解&#xff0c;用于将HTTP请求映射到相应的处理器类或处理器方法上。通过这种方式…...

若依移动版使用微信小程序打开失败

现象 解决办法&#xff1a;删掉自带的appid...

精准控图工具 Concept Sliders:超好用的 控制 Lora 适配器

Concept Sliders 你有没有遇到这样的情况&#xff1f;你花费大量时间制作提示和寻找种子&#xff0c;以使用文本到图像模型生成所需的图像。但是&#xff0c;你还需要对生成图像中的属性强度&#xff08;如眼睛大小或照明&#xff09;进行更细致、更精细的控制。修改提示会破坏…...

【EI会议征稿通知】第四届材料工程与应用力学国际学术会议(ICMEAAE 2025)

第四届材料工程与应用力学国际学术会议&#xff08;ICMEAAE 2025&#xff09; 2025 4th International Conference on Materials Engineering and Applied Mechanics 本次会议将重点讨论材料科学、应用力学等领域的最新研究进展与发展趋势。会议旨在为国内外从事这些领域研究…...

Hadoop安全之Knox

Apache Knox 是一个 REST API 网关&#xff0c;为 Hadoop 集群提供安全的访问方式。Knox 提供了一层保护&#xff0c;简化了对 Hadoop 生态系统&#xff08;如 HDFS、YARN、Hive、HBase 等&#xff09;中各个组件的访问&#xff0c;并通过单点登录 (SSO)、认证、授权和审计功能…...

SprinBoot+Vue应急信息管理系统的设计与实现

目录 1 项目介绍2 项目截图3 核心代码3.1 Controller3.2 Service3.3 Dao3.4 application.yml3.5 SpringbootApplication3.5 Vue 4 数据库表设计5 文档参考6 计算机毕设选题推荐7 源码获取 1 项目介绍 博主个人介绍&#xff1a;CSDN认证博客专家&#xff0c;CSDN平台Java领域优质…...

索尼研究的AI部门将与AI新加坡合作开发大型语言模型

索尼研究公司签署了一项合作协议&#xff0c;以帮助测试和优化东南亚语言一网通&#xff08;SEA-LION&#xff09;人工智能&#xff08;AI&#xff09;模型&#xff0c;重点关注印度语言。 索尼研究公司的AI部门将与负责开发AI新加坡&#xff08;AISG&#xff09;的公司合作&a…...

【OJ刷题】双指针问题

这里是阿川的博客&#xff0c;祝您变得更强 ✨ 个人主页&#xff1a;在线OJ的阿川 &#x1f496;文章专栏&#xff1a;OJ刷题入门到进阶 &#x1f30f;代码仓库&#xff1a; 写在开头 现在您看到的是我的结论或想法&#xff0c;但在这背后凝结了大量的思考、经验和讨论 目录 1…...

基于SpringBoot+Vue+MySQL的校园食堂订餐

系统展示 用户前台界面 管理员后台界面 系统背景 随着信息技术的飞速发展和互联网的普及&#xff0c;传统校园食堂的运作模式已难以满足现代学生日益增长的便捷性、个性化需求。学生们希望能够在忙碌的学习生活中&#xff0c;通过更加高效、便捷的方式完成就餐选择&#xff0c;…...

uniapp业务实现

uni.requset添加异常判断提示,以及加载动画 /*** 该函数用于发送网络请求获取数据* 请求失败时会弹出相应的错误提示* 请求成功时会检查返回的数据是否存在错误&#xff0c;并根据错误代码做出相应处理* 如果数据请求成功且无错误&#xff0c;则将返回的数据赋值给pets变量*/fu…...

Windows和Mac命令窗快速打开文件夹

Windows explorer . 和 macOS open . 命令详解 1. Windows explorer . explorer 是 Windows 上的文件资源管理器&#xff0c;用于通过命令行打开文件夹或文件。 常用命令格式&#xff1a; explorer [选项] [目标路径]. 表示当前目录&#xff0c;explorer . 打开当前工作目录…...

智能制造云平台---附源码79117

目 录 摘要 1 绪论 1.1 研究背景和意义 1.2开发技术 1.2.1 Flask框架 1.2.2 Python简介 1.2.3 MySQL数据库 1.3论文结构与章节安排 2系统分析 2.1 可行性分析 2.2总体设计原则 2.3 系统流程分析 2.3.1 用户登录流程 2.3.2 删除信息流程 2.4 系统角色分析 2.5 系…...

降本、创新、合作,谁才是连接器行业破除内卷的关键词?

如果用一个字来评价2024年的汽车行业&#xff0c;那就是「卷」。 ▲中国汽车保有量不断提升 图/Pixabay 长安汽车董事长朱华荣说&#xff1a;“汽车行业的卷&#xff0c;让中国品牌达到了新高度。” 吉利董事长李书福说&#xff1a;“中国汽车工业内卷程度全球第一&#xff0c;…...

可能一拆为二,英特尔为何走到今天这一步?

【科技明说 &#xff5c; 科技热点关注】 近来看到外媒消息说&#xff0c;英特尔迫于经营压力&#xff0c;也不得不铤而走险&#xff0c;欲将英特尔一分为二&#xff0c;即芯片制造与芯片设计分离开&#xff0c;互相剥离&#xff0c;独立发展。 于是乎&#xff0c;英特尔将分拆…...

了解Redis集群概念,集群如何选举主节点

请给胡广一个免费的三连吗&#xff1f;感谢&#xff01; 1. Redis集群 1.1 集群概念 Redis主从架构和Redis集群架构是两种不同的概念&#xff0c;大家刚接触Redis时经常弄混淆。胡广给大家贴下Redis官网对两者的解释。 &#xff08;1&#xff09;Redis主从架构 Redis主从实…...

Ozon跨境商家提升销量的关键:测评补单策略与必备条件

Ozon&#xff0c;自1998年创立以来&#xff0c;已稳居俄罗斯多品类电商领域的领导地位&#xff0c;不仅是俄罗斯最为人所熟知的电商品牌&#xff0c;更是该国电商行业的先驱之一。那么&#xff0c;对于希望在Ozon平台上实现销售爆单的跨境卖家而言&#xff0c;他们需要满足哪些…...

缺乏大模型经验,还有机会吗?

做大模型一年半&#xff0c;经历了无数场面试。 关于经验&#xff0c;我最常听到的候选人(尤其是学生)的说辞是:我没有大模型经验&#xff0c;可以给个机会吗&#xff1f;答案是&#xff0c;我们并不看重候选人的大模型训练经验。这里不是说经验不重要&#xff0c;而是大部分人…...

如何阅读李冬梅老师《数据结构》

根据《如何阅读一本书》第五章&#xff1a;主动阅读的基础&#xff1a;阅读者要提出的4个基本问题&#xff1f; 以第2章&#xff0c;线性表为例&#xff1a; &#xff08;1&#xff09;本章主要在谈些什么&#xff1f;例如第二章简介&#xff0c;读完这一章可以自己试着写个简…...

Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例

使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件&#xff0c;常用于在两个集合之间进行数据转移&#xff0c;如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model&#xff1a;绑定右侧列表的值&…...

centos 7 部署awstats 网站访问检测

一、基础环境准备&#xff08;两种安装方式都要做&#xff09; bash # 安装必要依赖 yum install -y httpd perl mod_perl perl-Time-HiRes perl-DateTime systemctl enable httpd # 设置 Apache 开机自启 systemctl start httpd # 启动 Apache二、安装 AWStats&#xff0…...

Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility

Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility 1. 实验室环境1.1 实验室环境1.2 小测试 2. The Endor System2.1 部署应用2.2 检查现有策略 3. Cilium 策略实体3.1 创建 allow-all 网络策略3.2 在 Hubble CLI 中验证网络策略源3.3 …...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院查看报告小程序

一、开发环境准备 ​​工具安装​​&#xff1a; 下载安装DevEco Studio 4.0&#xff08;支持HarmonyOS 5&#xff09;配置HarmonyOS SDK 5.0确保Node.js版本≥14 ​​项目初始化​​&#xff1a; ohpm init harmony/hospital-report-app 二、核心功能模块实现 1. 报告列表…...

IoT/HCIP实验-3/LiteOS操作系统内核实验(任务、内存、信号量、CMSIS..)

文章目录 概述HelloWorld 工程C/C配置编译器主配置Makefile脚本烧录器主配置运行结果程序调用栈 任务管理实验实验结果osal 系统适配层osal_task_create 其他实验实验源码内存管理实验互斥锁实验信号量实验 CMISIS接口实验还是得JlINKCMSIS 简介LiteOS->CMSIS任务间消息交互…...

UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)

UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中&#xff0c;UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化&#xf…...

Redis数据倾斜问题解决

Redis 数据倾斜问题解析与解决方案 什么是 Redis 数据倾斜 Redis 数据倾斜指的是在 Redis 集群中&#xff0c;部分节点存储的数据量或访问量远高于其他节点&#xff0c;导致这些节点负载过高&#xff0c;影响整体性能。 数据倾斜的主要表现 部分节点内存使用率远高于其他节…...

Linux 中如何提取压缩文件 ?

Linux 是一种流行的开源操作系统&#xff0c;它提供了许多工具来管理、压缩和解压缩文件。压缩文件有助于节省存储空间&#xff0c;使数据传输更快。本指南将向您展示如何在 Linux 中提取不同类型的压缩文件。 1. Unpacking ZIP Files ZIP 文件是非常常见的&#xff0c;要在 …...

莫兰迪高级灰总结计划简约商务通用PPT模版

莫兰迪高级灰总结计划简约商务通用PPT模版&#xff0c;莫兰迪调色板清新简约工作汇报PPT模版&#xff0c;莫兰迪时尚风极简设计PPT模版&#xff0c;大学生毕业论文答辩PPT模版&#xff0c;莫兰迪配色总结计划简约商务通用PPT模版&#xff0c;莫兰迪商务汇报PPT模版&#xff0c;…...

Ubuntu系统复制(U盘-电脑硬盘)

所需环境 电脑自带硬盘&#xff1a;1块 (1T) U盘1&#xff1a;Ubuntu系统引导盘&#xff08;用于“U盘2”复制到“电脑自带硬盘”&#xff09; U盘2&#xff1a;Ubuntu系统盘&#xff08;1T&#xff0c;用于被复制&#xff09; &#xff01;&#xff01;&#xff01;建议“电脑…...