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

一文学会gtest UT测试编写(TEST\TEST_F)

目录

一、官方文档&代码

二、不同平台导入gtest静态库

Android工程

Linux

三、UT测试 Step by Step

1. 示例入门

 2. 断言 EXPECT 与 ASSERT

 3. TEST与TEST_F

TEST

TEST_F

4. gmock


Google Test(简称 gtest)是 Google C++ 测试框架,用于编写和运行单元测试、集成测试和功能测试。它是一个功能丰富且易于使用的测试框架,旨在帮助开发人员编写可靠和高效的 C++ 测试代码。

一、官方文档&代码

GoogleTest User’s Guide | GoogleTest

GitHub - google/googletest: GoogleTest - Google Testing and Mocking Framework

二、不同平台导入gtest静态库

Android工程

aosp自带静态库,头文件在标准库中,所以使用很方便。

至少包含下面的库

LOCAL_STATIC_LIBRARIES +=   \
    libgtest

使用时直接包含头文件即可

#include <gtest/gtest.h>

Linux

一般自己编译,或直接取编译好的使用

编译方法

# 下载gtest源文件
git clone https://github.com/google/googletest.git

# build需要的静态库
# 新建build是为了让编译生成的文件都在这个目录下,整洁
cd googletest/
mkdir build
cd build/
# cmake会根据CMakeLists.txt文件生成Makefile文件
# make生成可执行文件(库)
cmake ..
make

看下生成产物:

对于简单的UT测试程序,只需要libgtest.a这个静态库。

三、UT测试 Step by Step

1. 示例入门

写个测试程序main.cpp

  1. 需要包含gtest.h头文件
  2. 不是必须要写main。如果没写main函数,可以引入libgtest_main.a代替,这个也是上节中的编译产物
#include <iostream>
#include <string>

#include "gtest/gtest.h"

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

TEST(Fun, AddTest)
{
    EXPECT_EQ(2, add(1, 1));
    EXPECT_EQ(0, add(1, -1));
}

int main(int argc, char **argv)
{

    ::testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}

编译运行

  1. 需要连接静态库+头文件
  2. c++版本要求>=14,依据Supported Platforms | GoogleTest
g++ main.cpp googletest/build/lib/libgtest.a -I googletest/googletest/include/ -o uint_test1 -std=c++14
./uint_test1

执行结果

 2. 断言 EXPECT 与 ASSERT

  • EXPECT_*:失败继续执行;
  • ASSERT_*:失败即终止。

由此可见,通常 EXPECT_* 是首选。

  1. ASSERT_* 是直接从当前函数返回的,可能会导致一些内存、文件资源没有释放,因此存在内存泄漏的问题。
  2. EXPECT_*可以继续执行完所有测试用例。

GoogleTest 提供了一系列断言:Assertions Reference | GoogleTest

 3. TEST与TEST_F

TEST

TEST(TestSuiteName, TestName) {
  ... test body ...
}
  • TestSuiteName 对应测试用例集名称,TestName 是归属的测试用例名称。测试的全名由其包含的测试用例集及其测试名称组成。来自不同测试用例集的测试可以具有相同的名称。
  • 这两个名称都必须是有效的 C++ 标识符,并且它们不应包含任何下划线。

TEST_F

如果很多测试都执行一样的操作,那就会用到TEST_F。实际上,这个最常使用,一定要看懂

TEST_F(TestFixtureName, TestName) {
  ... test body ...
}

Fixture,其语义是固定的设施,而 test fixture 在 GoogleTest 中的作用就是为每个 TEST 都执行一些同样的操作。

TestFixtureName 继承 testing::Test 类,然后根据我们的需要实现下面这两个虚函数:

  • virtual void SetUp():在 TEST_F 之前,构造函数之后运行;
  • virtual void TearDown():在 TEST_F 之后,析构函数之前运行。

此外 testing::Test 还提供了两个 static 函数:

  • static void SetUpTestSuite():在第一个 TEST 之前运行
  • static void TearDownTestSuite():在最后一个 TEST 之后运行

全局事件,即继承testing::Environment,需要调用AddGlobalTestEnvironment使能,并实现下面两个虚函数:

  • virtual void SetUp():在所有用例之前运行;
  • virtual void TearDown():在所有用例之后运行。

举例说明

#include <iostream>
#include <string>

#include "gtest/gtest.h"

class EnvironmentNew : public ::testing::Environment
{
public:
    ~EnvironmentNew() override {}

    // Override this to define how to set up the environment.
    void SetUp() override
    {
        std::cout << "Environment SetUp" << std::endl;
    }

    // Override this to define how to tear down the environment.
    void TearDown() override
    {
        std::cout << "Environment TearDown" << std::endl;
    }
};

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

// The fixture for testing class Foo.
class FooTest : public testing::Test
{
protected:
    // You can remove any or all of the following functions if their bodies would
    // be empty.

    FooTest()
    {
        // You can do set-up work for each test here.
        std::cout << "FooTest Constructor" << std::endl;
    }

    ~FooTest() override
    {
        // You can do clean-up work that doesn't throw exceptions here.
        std::cout << "FooTest Destructor" << std::endl;
    }

    // If the constructor and destructor are not enough for setting up
    // and cleaning up each test, you can define the following methods:

    void SetUp() override
    {
        // Code here will be called immediately after the constructor (right
        // before each test).
        std::cout << "FooTest SetUp" << std::endl;
    }

    void TearDown() override
    {
        // Code here will be called immediately after each test (right
        // before the destructor).
        std::cout << "FooTest TearDown" << std::endl;
    }

    // Class members declared here can be used by all tests in the test suite
    // for Foo.

    static void SetUpTestSuite()
    {
        std::cout << "FooTest SetUpTestSuite" << std::endl;
    }

    static void TearDownTestSuite()
    {
        std::cout << "FooTest TearDownTestSuite" << std::endl;
    }
};

TEST_F(FooTest, AddTest1)
{
    EXPECT_EQ(2, add(1, 1));
}

TEST_F(FooTest, AddTest2)
{
    EXPECT_EQ(0, add(1, -1));
}

TEST_F(FooTest, AddTest3)
{
    EXPECT_EQ(-2, add(-1, -1));
}

int main(int argc, char **argv)
{
    // AddGlobalTestEnvironment非必须
    // 可在main外部定义全局变量调用testing::AddGlobalTestEnvironment,保证在RUN_ALL_TESTS前执行
    // 不需要手动delete
    testing::AddGlobalTestEnvironment(new EnvironmentNew());

    ::testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}

编译执行

g++ main1.cpp googletest/build/lib/libgtest.a -I googletest/googletest/include/ -o uint_test1 -std=c++14

执行结果

4. gmock

gmock用来模拟对外部对象的依赖,可以指定模拟对象在测试中应该被调用的次数、调用的顺序以及调用时传入的参数等条件。这有助于确保被测试代码与依赖的交互符合预期,而无需实际依赖于外部资源

本文暂时不做详细描述,实际工作中用的不算多。提供一些参考资料:

Mocking Reference | GoogleTest

【gmock】Google Mock 入门-CSDN博客


http://www.kler.cn/a/229651.html

相关文章:

  • 【后端面试总结】Golang可能的内存泄漏场景及应对策略
  • SQL美化器优化
  • LLaMA-Factory web微调大模型并导出大模型
  • 【手写数据库toadb】虚拟文件描述符,连接表对象与物理文件的纽带,通过逻辑表找到物理文件的密码
  • 【数据结构笔记】线性表(代码)
  • 《动手学深度学习(PyTorch版)》笔记7.4
  • 每日一题(づ ̄3 ̄)づ╭❤~(数字在升序数组中出现的次数,整数转换)
  • arm 汇编积累
  • 节点确认交易全过程
  • docker下拉(pull)镜像和生成容器,文章尾部有常用的linux命令
  • PHP实现DESede/ECB/PKCS5Padding加密算法兼容Java SHA1PRNG
  • Jgit Packfile is truncated解决方案
  • c++中的char[] ,char* ,string三种字符串变量转化的兼容原则
  • Unity_ShaderGraph节点问题
  • e^{ix} 的 conjugate value(复共轭)
  • 易点易动设备管理系统——精确管理BOM,提升生产效率
  • 【AI绘画+Midjourney平替】Fooocus:图像生成、修改软件(Controlnet原作者重新设计的UI+Windows一键部署)
  • Autovue R21.1 发布
  • Flask 入门4:Flask 模板
  • 容器化技术基础概念:雪花服务器与凤凰服务器
  • IEC61499 学习记录
  • 敏捷软件研发管理流程- scrum
  • VXLAN:虚拟化网络的强大引擎