一文掌握开源单元测试框架Google Test

我们在开发的过程中,需要做一些验证测试,来保证我们的代码是按照设计要求工作的,这就需要单元测试了。单元测试(Unit Test),我们称为“UT测试”。对于一个复杂的系统来说,需要编写大量的单元测试用例,有人会觉得这么多的测试代码,将会花费大量的时间,影响开发的进度,会得不偿失。真的是这样吗?其实,对于越是复杂的系统就越是需要单元测试来保证我们的代码的开发质量,及时测试出代码的问题,在开发阶段发现问题总比在系统发布之后发现问题能够较少的节省资源或成本。

对于单元测试应该是每个开发工程师必备的技能,尤其是高阶的开发工程师会更加注重UT的重要性。同时,我们在开发功能模块之前会考虑到测试用例的实现,这样自然的就会考虑到功能模块的模块化便于UT的编写,从这一方面来说也能提高开发人员开发的代码质量。另外,单元测试用例还可以作为示例供开发人员参考,从而能够更轻松的掌握模块的使用。

今天就和大家一起学习一个开源的C++的单元测试框架Google test,大家看名字就知道它是由牛逼的Google公司出品。Google Test可以在多种平台上使用,它可以支持:

Linux、Mac OS X、Windows、Cygwin、MinGW、Windows Mobile、Symbian、PlatformIO等。

安装和配置

我们可以从github获取Google Test的源码,如果大家没有github账号也可以从网盘下载。

github下载地址: https://github.com/google/googletest
网盘下载:关注公众号【Will的大食堂】回复【gTest下载】即可获取下载地址。

因为我们下载到的gTest是源代码,还需要将其编译成库文件再进行使用。下面将和大家一起学习如何在windows环境下生成gTest的库文件。在这之前我们需要安装CMake和MinGW,大家可以参考下面这两个文章进行安装。

将下载的gTest的源码进行解压,源码目录如下图所示。

源码工程目录

打开命令行工具cmd,进入源码的工程目录,新建一个build目录用来存放构建文件,然后,进入build目录执行cmake命令生成Makefile文件。

mkdir build
cd build
cmake -G "MinGW Makefiles" ..

执行cmake
生成makefile

Makefile文件生成后,再执行下面的命令mingw32-make编译库文件。编译成功后就会发现有libgtest.a 和libgtest_main.a两个静态库生成。这里注意,Windows下mingw安装的make工具名称是mingw32-make而不是make。

mingw32-make

执行mingw32-make命令

接下来我们在VS Code写一个测试用例,使用生成的gTest静态库测试下。按下快捷键【Ctrl+Shift+p】,在弹出的搜索框中搜索【C/C++:Edit Configurations】,可以创建c_cpp_properties.json配置文件。

C/C++:Edit Configurations

在c_cpp_properties.json配置文件添加gTest的头文件目录。

添加gTest头文件目录

在task.json配置文件中添加gTest头文件目录和库文件,task.json配置文件可以通过菜单栏中Terminal选项下的【Configure Default Build Task】选项创建,可以参照之前的文章。

Configure Default Build Task

添加头文件目录和库文件

上面配置好之后,我们写个测试用例跑一下。

#include <iostream>
#include <gtest/gtest.h>

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

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

TEST(testcase, test_add)
{
   
    EXPECT_EQ(add(1,2), 3);
    EXPECT_EQ(sub(1,2), -1);
}

int main(int argc, char **argv)
{
     
    std::cout << "run google test --> " << std::endl << std::endl;
    testing::InitGoogleTest(&argc, argv);  
    return RUN_ALL_TESTS(); 
} 

运行结果如下图所示,代码中的TEST是一个宏,用来创建测试用例,它有test_case_name和test_name两个参数。分别是测试用例名和测试名,在后面的文章中我们会对其有更深刻的理解,这里就不细说了。RUN_ALL_TESTS也是一个宏,它是测试用例的入口。EXPECT_EQ这个是一个断言相关的宏,用来检测两个数值是否相等。

运行结果

断言

除了上面示例里的EXPECT_EQ,在gTest里有很多断言相关的宏。断言可以检查出某些条件的真假,因此,我们可以通过它来判断被测试的函数的成功与否。这里断言我们主要可以分为两类:

  • 以"ASSERT_"开头的断言,致命性断言(Fatal assertion)
  • 以"EXPECT_"开头的断言 ,非致命性断言(Nonfatal assertion)

上面的两种断言会在断言条件不满足时会有区别,即当不满足条件时, "ASSERT_"断言会在当前函数终止,而不会继续执行下去;而"EXPECT_"则会继续执行。我们可以通过下面一个例子来理解下他们的区别。

#include <iostream>
#include <gtest/gtest.h>

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

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

TEST(testcase, test_expect)
{
   
    std::cout << "------ test_expect start-----" << std::endl;

    std::cout << "add function start" << std::endl;
    EXPECT_EQ(add(1,2), 2);
    std::cout << "add function end" << std::endl;

    std::cout << "sub function start" << std::endl;
    EXPECT_EQ(sub(1,2), -1);
    std::cout << "sub function end" << std::endl;

    std::cout << "------ test_expect end-----" << std::endl;
}

TEST(testcase, test_assert)
{
   

    std::cout << "------ test_assert start-----" << std::endl;

    std::cout << "add function start" << std::endl;
    ASSERT_EQ(add(1,2), 2);
    std::cout << "add function end" << std::endl;

    std::cout << "sub function start" << std::endl;
    ASSERT_EQ(sub(1
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值