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

LinuxC++——gtest框架入门

gtest

  • Google Test(GTest)
    • 一、GTest 的下载与安装
      • 1. 源码下载
      • 2. 编译安装(Linux)
    • 二、GTest 的核心特点
    • 三、基本使用方法
      • 1. 简单测试示例
      • 2. 编译运行
    • 四、核心函数与宏
      • 1. 断言宏
      • 2. 测试夹具(Test Fixture)
        • 一、测试夹具的基本结构
        • 二、具体示例:测试计算器类
        • 三、执行流程与输出解析
        • 四、关键注意事项
      • 3. 参数化测试
      • 4. 死亡测试
    • 五、运行参数
    • 六、注意事项

Google Test(GTest)

Google Test(简称 GTest)是 Google 开发的 C++ 单元测试框架,广泛用于 C++ 项目的单元测试。以下是其下载安装、特点、使用方法及相关细节的详细介绍。

一、GTest 的下载与安装

1. 源码下载

源代码克隆:

# 从GitHub克隆源码
git clone https://github.com/google/googletest.git
cd googletest

直接下载安装包:

sudo apt install libgtest-dev
[sudo] person 的密码: 
正在读取软件包列表... 完成
正在分析软件包的依赖关系树... 完成
正在读取状态信息... 完成                 
下列软件包是自动安装的并且现在不需要了:libgl1-amber-dri libglapi-mesa libllvm19
使用'sudo apt autoremove'来卸载它(它们)。
将会同时安装下列软件:googletest
下列【新】软件包将被安装:googletest libgtest-dev
升级了 0 个软件包,新安装了 2 个软件包,要卸载 0 个软件包,有 3 个软件包未被升级。
需要下载 789 kB 的归档。
解压缩后会消耗 5,160 kB 的额外空间。
您希望继续执行吗? [Y/n] y
获取:1 https://mirrors.tuna.tsinghua.edu.cn/ubuntu noble/universe amd64 googletest all 1.14.0-1 [521 kB]
获取:2 https://mirrors.tuna.tsinghua.edu.cn/ubuntu noble/universe amd64 libgtest-dev amd64 1.14.0-1 [268 kB]
已下载 789 kB,耗时 3(268 kB/s)    
debconf: 无法初始化前端界面:Dialog
debconf: (对话框界面要求屏幕画面必须为至少 13 行高及 31 列宽.)
debconf: 返回前端界面:Readline
正在选中未选择的软件包 googletest。
(正在读取数据库 ... 系统当前共安装有 292834 个文件和目录。)
准备解压 .../googletest_1.14.0-1_all.deb  ...
正在解压 googletest (1.14.0-1) ...
正在选中未选择的软件包 libgtest-dev:amd64。
准备解压 .../libgtest-dev_1.14.0-1_amd64.deb  ...
正在解压 libgtest-dev:amd64 (1.14.0-1) ...
正在设置 googletest (1.14.0-1) ...
正在设置 libgtest-dev:amd64 (1.14.0-1) ...

2. 编译安装(Linux)


# 创建构建目录
mkdir build && cd build# 生成Makefile(需要CMake)
cmake .. -DCMAKE_INSTALL_PREFIX=/usr/local# 编译并安装
make -j4
sudo make install

安装完成后,头文件会被安装到/usr/local/include,库文件到/usr/local/lib。

二、GTest 的核心特点

丰富的断言宏:提供了 ASSERT_(失败时终止当前函数)和 EXPECT_(失败时继续执行)两类断言,支持多种数据类型比较。

测试夹具(Test Fixture):通过继承testing::Test类,实现多个测试用例共享初始化和清理代码。

测试套件(Test Suite):将相关测试用例组织成测试套件,便于管理。

参数化测试:支持同一测试逻辑用不同参数多次执行。

死亡测试(Death Test):用于测试程序在特定条件下是否会崩溃或退出。

良好的兼容性:支持 C++11 及以上标准,可与 CMake、Autotools 等构建工具集成。

三、基本使用方法

1. 简单测试示例

#include "gtest/gtest.h"
#include <iostream>
using std::cout;
using std::endl;bool isEven(int num)
{return num % 2 == 0;
}TEST(测试案例, 测试案例一)
{ASSERT_TRUE(isEven(4));EXPECT_TRUE(isEven(8));EXPECT_TRUE(isEven(3));ASSERT_TRUE(isEven(7));
}int main(int argc, char* argv[])
{testing::InitGoogleTest(&argc, argv);return RUN_ALL_TESTS();
}

2. 编译运行

g++ test.cpp -o test -lgtest -lgtest_main -pthread
./test
  • -lgtest:链接 GTest 库(必要)
  • -lgtest_main:使用 GTest 提供的 main 函数(若自定义 main 则可省略)
  • -pthread:GTest 依赖线程库
    在这里插入图片描述

四、核心函数与宏

1. 断言宏

类型功能示例
ASSERT_EQ断言相等(失败终止)ASSERT_EQ(a, b)
ASSERT_NE断言不等ASSERT_NE(a, b)
ASSERT_LT断言小于ASSERT_LT(a, b)
ASSERT_TRUE断言为 trueASSERT_TRUE(condition)
EXPECT_EQ断言相等(失败继续)EXPECT_EQ(a, b)
EXPECT_STREQ字符串相等(C 风格)EXPECT_STREQ(str1, str2)
EXPECT_THROW断言抛出指定异常EXPECT_THROW(func(), exception_type)

2. 测试夹具(Test Fixture)

当多个测试用例需要共享数据或初始化逻辑时使用:

一、测试夹具的基本结构

测试夹具通过继承testing::Test类实现,核心是重写两个虚函数:

  • SetUp():每个测试用例执行前调用(初始化资源)

  • TearDown():每个测试用例执行后调用(清理资源)

此外还有两个静态函数用于全局资源管理

  • SetUpTestSuite():整个测试套件开始前调用一次

  • TearDownTestSuite():整个测试套件结束后调用一次

二、具体示例:测试计算器类

假设我们有一个Calculator类,需要测试其加法、减法功能,且所有测试都需要先创建Calculator对象。
1. 被测试代码(calculator.h)

#ifndef CALCULATOR_H
#define CALCULATOR_Hclass Calculator {
public:int add(int a, int b) { return a + b; }int subtract(int a, int b) { return a - b; }
};#endif // CALCULATOR_H

2. 测试夹具实现(test_calculator.cpp)

#include <gtest/gtest.h>
#include "calculator.h"// 定义测试夹具类,继承testing::Test
class CalculatorTest : public testing::Test {
protected:// 静态成员:所有测试用例共享的资源static Calculator* shared_calc;// 每个测试用例执行前调用(初始化)void SetUp() override {// 为当前测试创建独立的Calculator实例calc = new Calculator();std::cout << "SetUp: 创建新的Calculator实例" << std::endl;}// 每个测试用例执行后调用(清理)void TearDown() override {delete calc; // 释放当前测试的资源std::cout << "TearDown: 销毁Calculator实例" << std::endl;}// 整个测试套件开始前调用(全局初始化)static void SetUpTestSuite() {shared_calc = new Calculator(); // 创建共享资源std::cout << "SetUpTestSuite: 创建共享Calculator" << std::endl;}// 整个测试套件结束后调用(全局清理)static void TearDownTestSuite() {delete shared_calc; // 释放共享资源std::cout << "TearDownTestSuite: 销毁共享Calculator" << std::endl;}// 成员变量:当前测试用例独享的资源Calculator* calc;
};// 初始化静态成员
Calculator* CalculatorTest::shared_calc = nullptr;// 使用TEST_F宏定义基于夹具的测试用例
TEST_F(CalculatorTest, AddTest) {// 可以访问夹具中的成员变量calc和静态成员shared_calcEXPECT_EQ(calc->add(2, 3), 5);EXPECT_EQ(shared_calc->add(-1, 1), 0);
}TEST_F(CalculatorTest, SubtractTest) {EXPECT_EQ(calc->subtract(5, 3), 2);EXPECT_EQ(shared_calc->subtract(0, 5), -5);
}// 主函数
int main(int argc, char **argv) {testing::InitGoogleTest(&argc, argv);return RUN_ALL_TESTS();
}
三、执行流程与输出解析

编译运行后,执行顺序如下:

SetUpTestSuite: 创建共享Calculator  // 全局初始化(一次)
SetUp: 创建新的Calculator实例        // AddTest前初始化
TearDown: 销毁Calculator实例         // AddTest后清理
SetUp: 创建新的Calculator实例        // SubtractTest前初始化
TearDown: 销毁Calculator实例         // SubtractTest后清理
TearDownTestSuite: 销毁共享Calculator // 全局清理(一次)

可以看到:

  • SetUpTestSuite()和TearDownTestSuite()仅执行一次(全局资源)
  • SetUp()和TearDown()对每个测试用例各执行一次(独立资源)
四、关键注意事项

测试独立性:每个测试用例通过SetUp()获得独立的资源(如calc),避免测试间相互干扰。例如:在AddTest中修改calc不会影响SubtractTest。

宏的使用:基于夹具的测试用例必须用TEST_F(TestFixtureName, TestName)定义,而非普通的TEST()。

成员访问权限:夹具中的资源(如calc)必须声明为protected,才能在测试用例中访问。

静态资源的谨慎使用:SetUpTestSuite()中的共享资源(如shared_calc)会被所有测试用例共享,若测试中修改其状态,可能导致测试依赖,需谨慎使用。

避免复杂逻辑:SetUp()和TearDown()应保持简洁,若包含复杂逻辑,建议封装为独立函数,避免影响测试效率。

3. 参数化测试

// 1. 定义参数化测试类
class ParamTest : public testing::TestWithParam<int> {};// 2. 定义测试用例
TEST_P(ParamTest, IsEven) {int n = GetParam(); // 获取当前参数EXPECT_EQ(IsEven(n), n % 2 == 0);
}// 3. 注册参数组合
INSTANTIATE_TEST_SUITE_P(EvenOddTests,        // 测试套件名称后缀ParamTest,           // 测试类testing::Values(0, 1, 2, 3, 4) // 参数列表
);

4. 死亡测试

用于测试程序是否按预期退出:

TEST(DeathTest, DivisionByZero) {// 断言程序会崩溃(返回非0状态)EXPECT_DEATH({ int x = 1 / 0; }, "");
}// 更精确的死亡测试(检查输出)
TEST(DeathTest, ExpectedMessage) {EXPECT_EXIT({ std::cout << "Error: Exit" << std::endl;exit(1); }, testing::ExitedWithCode(1), "Error: Exit");
}

五、运行参数

执行测试程序时可带参数控制测试行为:

参数功能
–gtest_list_tests列出所有测试用例,不执行
–gtest_filter=PATTERN只执行匹配 PATTERN 的测试(如 “IsEvenTest*”)
–gtest_repeat=N重复执行测试 N 次(N=0 表示无限重复)
–gtest_break_on_failure测试失败时暂停(用于调试)
–gtest_output=xml:filename生成 XML 格式的测试报告

六、注意事项

断言选择:

  • ASSERT_* 失败时会终止当前测试函数,适合关键检查。
  • EXPECT_* 失败时继续执行,适合需要多个检查点的场景。

测试独立性:每个测试用例应独立,不依赖其他测试的执行结果或顺序。

夹具使用:SetUp() 和 TearDown() 会为每个测试用例执行一次,避免测试间状态污染。

编译链接:确保链接时包含 -lgtest 和 -pthread,否则会出现链接错误。

异常处理:若代码中使用异常,需用 EXPECT_THROW 等宏捕获,避免测试崩溃。

性能考虑:复杂测试可使用 TEST_F 的 SetUpTestSuite() 初始化全局资源,减少重复开销。

GTest 通过简洁的 API 和丰富的功能,帮助开发者编写可靠的单元测试,是 C++ 项目中单元测试的首选框架之一。

http://www.dtcms.com/a/415664.html

相关文章:

  • 云南信息发布平台seo页面内容优化
  • 做网站英文编辑有前途吗北京招聘网站建设
  • 什么是Transformer?
  • 手机网站显示建设中鄂尔多斯 网站制作
  • wordpress制作大型网站网站建设公司86215
  • 徐州网站制作功能哪里有门户网站开发
  • 电脑行业网站模板福建省交通建设质量安全监督局网站
  • 面试官常问:NULL 对聚合函数的影响
  • 汕头模板做网站贵州省建设局八大员报名网站
  • Excel判断身份证号是否正确
  • 神经正切核(NTK):从梯度流到核方法的完整推导
  • 想在浏览器里跑 AI?TensorFlow.js 硬件支持完全指南
  • 安徽省城乡住房建设厅网站沧县官厅网站建设
  • 网站开发北京虚拟主机做网站教程
  • WSL 安装方法(简单全面)
  • 京东100道GO面试题及参考答案(上)
  • 网站被挂黑链怎么处理深圳宝安网站建设公司推荐
  • h5网站模板下载wordpress加速访问
  • 语言大模型(LLM)与自然语言处理(NLP)
  • 如何构建网站重庆中技互联
  • QML学习笔记(十五)QML的信号处理器(MouseArea)
  • php 微信 网站建设无限观影次数的app软件
  • 苏州网站建设数据网络WordPress支付宝登录
  • opcode - Claude Code 图形化工具集
  • 淮南招聘网站建设全球域名注册平台
  • VsCode配置Claude Code-Windows
  • 网站建设台词精品课程网站设计说明范文
  • 手写MyBatis第78弹:装饰器模式在MyBatis二级缓存中的应用:从LRU到防击穿的全方案实现
  • 山西网站开发二次开发拍卖网站功能需求文档
  • 中文简洁网站设计图wordpress 导航菜单设置