gtest实战入门:从安装到TEST宏的单元测试指南

文章目录

  • [一、gtest 介绍](#一、gtest 介绍)
  • [二、gtest 安装](#二、gtest 安装)
  • [三、gtest 使用](#三、gtest 使用)
    • [1. 包含头文件](#1. 包含头文件)
    • [2. 框架初始化接口](#2. 框架初始化接口)
    • [3. 调用所有测试样例 的接口](#3. 调用所有测试样例 的接口)
    • [4. TEST 宏(创建一个独立测试)](#4. TEST 宏(创建一个独立测试))
    • [5. 断言宏](#5. 断言宏)
    • [6. 示例演示(含两种断言宏 的效果对比)](#6. 示例演示(含两种断言宏 的效果对比))

一、gtest 介绍

GTest 是一个跨平台的 C++单元测试框架,由 google 公司发布。gtest 是为了在不同平台上为编写 C++单元测试而生成的。它提供了丰富的断言、致命和非致命判断、参数化等等测试所需的宏,以及全局测试,单元测试组件。

二、gtest 安装

(1)直接命令安装(适用于 Ubuntu/Debian 系统):

bash 复制代码
sudo apt-get install libgtest-dev

(2)验证安装:

  • 检查头文件: ls /usr/include/gtest/
  • 检查库文件: ls /usr/lib/x86_64-linux-gnu/libgtest*

三、gtest 使用

1. 包含头文件

使用 gtest 库时必须包含如下头文件:

cpp 复制代码
#include <gtest/gtest.h>

2. 框架初始化接口

框架初始化接口:

cpp 复制代码
testing::InitGoogleTest(&argc, argv);

3. 调用所有测试样例 的接口

(1)调用所有测试样例 的接口:

cpp 复制代码
RUN_ALL_TESTS();

(2)返回值:

  • 返回 0: 所有测试用例(包括 TEST 和 TEST_F)全部通过,无任何断言失败或崩溃。
  • 返回 1: 至少有一个测试失败(断言失败、崩溃或未处理的异常)。

(3)关键使用规则:

  • 仅调用一次 RUN_ALL_TESTS()

    // 多次调用 RUN_ALL_TESTS() 会破坏框架内部状态(如线程安全的死亡测试),导致未定义行为

  • 使用 RUN_ALL_TESTS() 前,必须执行 testing::InitGoogleTest(&argc, argv) 初始化框架结构

  • 最佳实践:一般在main函数return时,调用 RUN_ALL_TESTS() 接口

典型使用示例:

cpp 复制代码
#include <gtest/gtest.h>

TEST(SampleTest, Pass) 
{ 
	EXPECT_EQ(1, 1);   // 通过
}  

TEST(SampleTest, Fail) 
{ 
	EXPECT_EQ(1, 2);   // 失败
}  

int main(int argc, char **argv) 
{
	// 使用 RUN_ALL_TESTS() 前,必须执行 testing::InitGoogleTest(&argc, argv) 初始化框架结构
  testing::InitGoogleTest(&argc, argv);
  
  // 最佳实践:一般在main函数return时,调用 RUN_ALL_TESTS() 接口
  return RUN_ALL_TESTS();  // 返回 1
}

4. TEST 宏(创建一个独立测试)

同测试下(测试名称相同),多个测试样例不能同名

cpp 复制代码
TEST(测试名称, 测试样例名称)
{
		// 测试内容
}
  • TEST: 主要用来创建一个简单测试, 它定义了一个测试函数, 在这个函数中可以使用任何 C++代码并且使用框架提供的断言进行检查

5. 断言宏

(1)GTest 中的断言的宏可以分为两类:

  • ASSERT_系列: 如果当前点检测失败,则退出当前函数(当前测试用例)
  • EXPECT_系列: 如果当前点检测失败,则继续往下执行

(2)下面是经常使用的断言介绍

cpp 复制代码
// bool 值检查
ASSERT_TRUE(参数),期待结果是 true
ASSERT_FALSE(参数),期待结果是 false

//数值型数据检查
ASSERT_EQ(参数 1,参数 2),传入的是需要比较的两个数 equal
ASSERT_NE(参数 1,参数 2),not equal,不等于才返回 true
ASSERT_LT(参数 1,参数 2),less than,小于才返回 true
ASSERT_GT(参数 1,参数 2),greater than,大于才返回 true
ASSERT_LE(参数 1,参数 2),less equal,小于等于才返回 true
ASSERT_GE(参数 1,参数 2),greater equal,大于等于才返回 true

6. 示例演示(含两种断言宏 的效果对比)

  • 项目结构:
bash 复制代码
.
├── main.cc
└── Makefile

./main.cc

cpp 复制代码
#include <gtest/gtest.h>

int Add(int a, int b) 
{ 
    return a + b; 
}

int sub(int a, int b)
{
    return a - b;
}

TEST(MathTest, add_test)
{
    ASSERT_EQ(Add(2, 3), 5);  // 5 == 5, 满足
    ASSERT_NE(Add(2, 3), 8);  // 5 != 8, 满足
    ASSERT_LT(Add(2, 3), 8);  // 5 < 8, 满足
}

// 同测试下(测试名称相同),多个测试样例不能同名
TEST(MathTest, sub_test)
{
    ASSERT_EQ(sub(5, 3), 3);  // 2 == 3, 不满足

    printf("你能看到这条打印信息嘛? \n");

    ASSERT_NE(sub(8, 3), 6);  // 5 != 6, 满足
}

int main(int argc, char **argv)
{
  // 使用 RUN_ALL_TESTS() 前,必须执行 testing::InitGoogleTest(&argc, argv) 初始化框架结构
  testing::InitGoogleTest(&argc, argv);
  
  // 最佳实践:一般在main函数return时,调用 RUN_ALL_TESTS() 接口
  return RUN_ALL_TESTS(); 
}

./Makefile

链接时,-l显式指定库名:gtest

bash 复制代码
main:main.cc
	g++ -o main main.cc -lgtest

  • 使用ASSERT系列的断言宏 的测试结果:

./main.cc

所有ASSERT系列的断言宏 改为 EXPECT系列

cpp 复制代码
#include <gtest/gtest.h>

int Add(int a, int b) 
{ 
    return a + b; 
}

int sub(int a, int b)
{
    return a - b;
}

TEST(MathTest, add_test)
{
    EXPECT_EQ(Add(2, 3), 5);  // 5 == 5, 满足
    EXPECT_NE(Add(2, 3), 8);  // 5 != 8, 满足
    EXPECT_LT(Add(2, 3), 8);  // 5 < 8, 满足
}

// 同测试下(测试名称相同),多个测试样例不能同名
TEST(MathTest, sub_test)
{
    EXPECT_EQ(sub(5, 3), 3);  // 2 == 3, 不满足

    printf("你能看到这条打印信息嘛? \n");

    EXPECT_NE(sub(8, 3), 6);  // 5 != 6, 满足
}

int main(int argc, char **argv)
{
  // 使用 RUN_ALL_TESTS() 前,必须执行 testing::InitGoogleTest(&argc, argv) 初始化框架结构
  testing::InitGoogleTest(&argc, argv);
  
  // 最佳实践:一般在main函数return时,调用 RUN_ALL_TESTS() 接口
  return RUN_ALL_TESTS(); 
}

  • 使用EXPECT系列的断言宏 的测试结果:

相关推荐
郝学胜-神的一滴2 小时前
墨韵技术|CMake:现代项目构建的「行云流水」之道
c++·程序人生·软件工程·软件构建·cmake
雪域迷影2 小时前
Hazel游戏引擎结构分析
c++·游戏引擎·hazel
“愿你如星辰如月”2 小时前
从零构建高性能 Reactor 服务器:
linux·服务器·c++·websocket·tcp/ip
努力努力再努力wz2 小时前
【C++高阶系列】外存查找的极致艺术:数据库偏爱的B+树底层架构剖析与C++完整实现!(附B+树实现的源码)
linux·运维·服务器·数据结构·数据库·c++·b树
Yungoal2 小时前
c++迭代器
开发语言·c++
rqtz2 小时前
【C++】ROS2捕获Ctrl+C信号+原子操作与线程生命周期控制
c++·多线程·原子
老四啊laosi11 小时前
[C++进阶] 24. 哈希表封装unordered_map && unordered_set
c++·哈希表·封装·unordered_map·unordered_set
妙为11 小时前
银河麒麟V4下编译Qt5.12.12源码
c++·qt·国产化·osg3.6.5·osgearth3.2·银河麒麟v4
史迪仔011215 小时前
[QML] QML IMage图像处理
开发语言·前端·javascript·c++·qt