首页 > 其他分享 >深入了解 Google Test (gtest):一份详细的指南

深入了解 Google Test (gtest):一份详细的指南

时间:2024-12-25 12:41:10浏览次数:7  
标签:Google TEST gtest EXPECT 测试 Test

Google Test(gtest)是 Google 提供的一款 C++ 测试框架,它广泛应用于 C++ 项目的单元测试。无论是初学者还是经验丰富的开发者,gtest 都是一个强大而灵活的工具,能够帮助你编写和执行单元测试,确保你的代码质量和稳定性。本文将从 gtest 的基本概念到高级特性,逐步带你深入了解如何使用它进行高效的 C++ 测试。

1. 什么是 Google Test?

Google Test 是 Google 开发的 C++ 测试框架,设计用于进行单元测试(Unit Testing)。它提供了丰富的断言(assertion)和测试机制,能够帮助开发者编写测试代码并自动执行,检测代码中的潜在缺陷。gtest 的目标是提供一个易于使用且强大的测试框架,兼具可扩展性和灵活性。

gtest 支持多种测试风格和断言方法,能够方便地集成到现有的 C++ 项目中,并且具有很好的跨平台支持。

2. gtest 的安装与配置

2.1 安装 gtest

使用 vcpkg 安装(Windows)

如果你在 Windows 环境下使用 Visual Studio,可以通过 vcpkg 安装 gtest:

vcpkg install gtest

使用 brew 安装(macOS)

在 macOS 上,你可以使用 Homebrew 来安装 gtest:

brew install googletest

从源码编译安装(通用)

你还可以直接从源码编译安装 Google Test。以下是一般的安装步骤:

  1. 克隆 gtest 仓库:

    git clone https://github.com/google/googletest.git
    
  2. 进入目录并创建构建文件夹:

    cd googletest
    mkdir build
    cd build
    
  3. 使用 CMake 生成构建文件并编译:

    cmake ..
    make
    sudo make install
    

2.2 配置 CMake

在你的 CMake 项目中集成 gtest,首先需要在 CMakeLists.txt 中找到 gtest,并将其链接到你的测试目标。可以参考以下配置:

# 找到并引入 Google Test
find_package(GTest REQUIRED)

# 包含头文件
include_directories(${GTEST_INCLUDE_DIRS})

# 你的测试目标
add_executable(my_test test.cpp)

# 链接 gtest 库
target_link_libraries(my_test ${GTEST_LIBRARIES} pthread)

3. 基本概念与用法

在 gtest 中,测试用例是由 测试夹具(Test Fixtures)测试用例(Test Cases) 组成的。

3.1 测试夹具(Test Fixture)

测试夹具是一个类,用来定义在多个测试用例中共享的初始化和清理操作。它可以看作是一个包含常用测试代码的模板,方便重复使用。测试夹具类需要继承自 ::testing::Test

例如:

#include <gtest/gtest.h>

class MyTestFixture : public ::testing::Test {
protected:
    // 初始化代码,测试之前运行
    void SetUp() override {
        // 设置操作
    }

    // 清理代码,测试之后运行
    void TearDown() override {
        // 清理操作
    }

    // 你可以在这里定义任何测试需要的成员
    int value = 42;
};

3.2 编写测试用例

在 gtest 中,测试用例通过宏 TEST_FTEST 定义。TEST_F 用于使用测试夹具,而 TEST 用于没有夹具的简单测试。

使用 TEST_F 和测试夹具

TEST_F(MyTestFixture, TestAddition) {
    EXPECT_EQ(value + 1, 43);  // 断言:value+1 等于 43
}

TEST_F(MyTestFixture, TestSubtraction) {
    EXPECT_EQ(value - 1, 41);  // 断言:value-1 等于 41
}

使用 TEST 编写无夹具的测试

TEST(MyTest, TestMultiplication) {
    int x = 5;
    int y = 10;
    EXPECT_EQ(x * y, 50);
}

3.3 断言(Assertions)

gtest 提供了丰富的断言宏,帮助你检查代码的行为是否符合预期。常用的断言有:

  • EXPECT_EQ(val1, val2):检查 val1 是否等于 val2。如果不等,测试继续执行。
  • ASSERT_EQ(val1, val2):检查 val1 是否等于 val2,如果不等,测试终止。
  • EXPECT_TRUE(val):检查 val 是否为 true
  • ASSERT_TRUE(val):检查 val 是否为 true,如果不为 true,测试终止。
  • EXPECT_FALSE(val):检查 val 是否为 false
  • ASSERT_FALSE(val):检查 val 是否为 false,如果不为 false,测试终止。
  • EXPECT_NE(val1, val2):检查 val1 是否不等于 val2
  • EXPECT_LT(val1, val2):检查 val1 是否小于 val2

例如:

TEST(MyTest, TestAssertions) {
    int a = 5;
    int b = 10;

    // 判断 a 是否小于 b
    EXPECT_LT(a, b);  
    // 判断 a 是否不等于 b
    EXPECT_NE(a, b);  
    // 判断 a 是否等于 5
    ASSERT_EQ(a, 5);  
}

4. 高级特性

4.1 测试参数化(Parameterized Tests)

gtest 允许你编写参数化的测试用例,便于重复测试多个输入数据。

定义参数化测试

class MyTestParam : public ::testing::TestWithParam<int> {
};

TEST_P(MyTestParam, TestMultiplication) {
    int input = GetParam();
    EXPECT_EQ(input * 2, input + input);
}

// 使用不同的参数集合执行测试
INSTANTIATE_TEST_SUITE_P(PositiveNumbers, MyTestParam, ::testing::Values(1, 2, 3, 4));

运行参数化测试

运行时,gtest 会为每个参数实例化一个测试用例,类似于:

[ RUN      ] MyTestParam.TestMultiplication/0
[       OK ] MyTestParam.TestMultiplication/0 (0 ms)
[ RUN      ] MyTestParam.TestMultiplication/1
[       OK ] MyTestParam.TestMultiplication/1 (0 ms)
...

4.2 自定义断言

有时,你可能需要编写自定义的断言。可以通过继承 ::testing::Matcher 来实现。以下是一个简单的例子:

#include <gtest/gtest.h>

class IsEven : public ::testing::MatcherInterface<int> {
public:
    explicit IsEven() {}

    bool MatchAndExplain(int n, ::testing::MatchResultListener* listener) const override {
        return n % 2 == 0;
    }

    void DescribeTo(std::ostream* os) const override {
        *os << "is an even number";
    }

    void DescribeNegationTo(std::ostream* os) const override {
        *os << "is not an even number";
    }
};

MATCHER(IsEven, "is an even number") {
    return arg % 2 == 0;
}

TEST(MyTest, CustomAssertion) {
    EXPECT_THAT(4, IsEven()); // 使用自定义断言
    EXPECT_THAT(5, Not(IsEven())); // 使用自定义断言并检查失败情况
}

5. 集成与持续集成(CI)

gtest 可以非常方便地与持续集成工具(如 Jenkins、GitHub Actions 等)结合使用。你只需在 CI 构建过程中运行测试命令,测试结果会自动报告并作为构建的反馈之一。

CMakeLists.txt 中添加测试支持,通常需要包含以下内容:

enable_testing()
add_test(NAME MyTest COMMAND my_test)

在 CI 环境中,你可以通过以下命令运行测试:

ctest

6. 总结

Google Test 是一个功能强大的 C++ 单元测试框架,提供了易于使用的 API 和广泛的功能,支持各种常见的单元测试需求,包括断言、参数化测试和自定义断言等。无论是对初学者还是经验丰富的开发者,gtest 都是一个非常有用的工具。通过本文的介绍,相信你已经对 gtest 的基本使用和高级特性有了更深入的了解

标签:Google,TEST,gtest,EXPECT,测试,Test
From: https://www.cnblogs.com/cypre/p/18630128

相关文章

  • Json转换工具类(基于google的Gson和阿里的fastjson)
    Json转换工具类(基于google的Gson和阿里的fastjson)|Id|Title|DateAdded|SourceUrl|PostType|Body|BlogId|Description|DateUpdated|IsMarkdown|EntryName|CreatedTime|IsActive|AutoDesc|AccessPermission||-------------|-------------|-------......
  • OpenAI 反击Google,推理ChatGPT模型“O3”猜想:慢思考与强智能的新探索
    近日,有国外媒体报道OpenAI其下一代推理模型“O3”即将问世。这款模型不仅在命名上跳过了传统序列逻辑,更在技术设计与推理理念上引发了广泛关注。“O3”的核心特性在于,它或许会放弃对速度和效率的过度追求,转而强化“慢思考”能力,让模型的推理方式更接近人类认知过程。这一改变......
  • 一站式Google Play应用上架服务,让您的应用快速上线
    随着智能手机的普及,手机应用已成为人们日常生活的一部分。GooglePlay作为全球最大的安卓应用商店,是开发者获取用户、推广产品的重要平台。然而,对于很多开发者而言,将应用顺利上架到GooglePlay并不是一件轻松的事情。审核标准严格、合规要求高、技术规范繁琐,常常让开发者面临重......
  • 使用Google Imagen在Vertex AI中生成、编辑和描述图像
    引言近年来,生成式AI技术正在迅速发展,特别是在图像生成领域。Google的Imagen技术通过VertexAI平台提供了卓越的图像生成能力,能够从文本提示中快速生成高质量的视觉资产。这为应用开发者提供了强大的工具,以创建下一代的AI产品,变用户的想象力为视觉现实。本篇文章将介绍Googl......
  • Ungoogled-Chromium 隐私安全浏览器
    ungoogled-chromium是来自GitHub的开源项目,是Chromium的衍生版本。它开源、免费、无广告,并且移除了所有来自Google的网络服务功能,包括自动更新功能,保证了隐私安全和浏览器性能。ungoogled-chromium目前支持Windows、MacOS、Linux等平台。除了没有Google服务之外,其......
  • pytest7.4.0后报错:fixture '方法名' not found
    当你python中的pytest升级到7.4.0(包含)后,会发现脚本报错了,如以下报错信息:fixture'start_driver'notfound找不到你的测试夹具 出现此问题不要慌,如果你之前脚本是可以正常执行,升级pytest后报此错误,那大概率就是pytest升级问题导致的。解决方法:不要改什么内容,只需要把你......
  • 中考阅读理解深入逻辑分析-003 The Confidence Test 信心测试
    文章正文Mr.Smithstoodbeforehisclassof30studentsandwasgoingtohandoutthefinalexampapers."Iknowhowhardyouhaveallworkedtogetreadyforthistest,"hesaid."AndbecauseIknowyouareallabletounderstandthesequesti......
  • 使用`typeof test === "object"`来判定test是否是对象有什么缺陷?如何避免?
    在JavaScript中,使用typeoftest==="object"来判断一个变量test是否为对象有一定的缺陷。这种方法的缺陷主要包括:无法区分null和对象:在JavaScript中,typeofnull的结果也是"object",这会导致当test为null时,上述判断也会返回true,这显然是不准确的。无法识别数组和null之外的其......
  • WPF HitTestResult
    usingSystem.Text;usingSystem.Windows;usingSystem.Windows.Controls;usingSystem.Windows.Data;usingSystem.Windows.Documents;usingSystem.Windows.Input;usingSystem.Windows.Media;usingSystem.Windows.Media.Imaging;usingSystem.Windows.Navigation;......
  • 一文搞懂 Google不同型号TPU显存
    起因:      最近在做具身智能相关的工作,看的多是google的文章,里面频繁出现类似WetrainourpoliciesonaTPUv38x8pod(64TPUv3chips),网上没有找到很清晰地关于不同型号TPU显存大小的说明,于是自己参考前辈的文章和官方文档总结了一份,有错误希望大家及时指出。......