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

本文详细介绍了GoogleTest单元测试框架的使用,包括官方文档、在Android和Linux平台上导入gtest静态库的方法,以及UT测试的步骤,涉及EXPECT和ASSERT的区别、TEST和TEST_F的用法,以及gmock模拟对象的简介。
摘要由CSDN通过智能技术生成

目录

一、官方文档&代码

二、不同平台导入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博客

  • 24
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值