google c++程序测试框架googletest使用教程详解

目录
  • 什么是googletest?
    • googletest简介
  • 谁在使用 GoogleTest?
  • 相关开源项目
  • googletest的下载与编译
  • cmake gui编译
  • 在vs2019中使用googletest
  • GTest的一些基本概念
  • GTest的断言
  • 事件机制
  • 参数化

什么是googletest?

googletest简介

​GoogleTest 是 Google 的 C++ 测试和模拟框架,可以帮助程序员测试C++程序的结果预期,GoogleTest 的代码用cmake管理,可以使用cmake进行编译程dll在程序中使用。googletest一般也可以简称为gtest, 最新版本GoogleTest 需要符合 C++11 标准或更新标准的代码库和编译器。

​ gtest官网:https://google.github.io/googletest/
​ git仓库:https://github.com/google/googletest

谁在使用 GoogleTest?

除了 Google 的许多内部项目,GoogleTest 还被以下著名项目使用:

  • 铬项目(Chrome浏览器和Chrome OS背后)。
  • LLVM编译器。
  • Protocol Buffers,Google 的数据交换格式。
  • OpenCV的计算机视觉库。 相关开源项目

相关开源项目

GTest Runner是一个基于 Qt5 的自动化测试运行器和图形用户界面,具有适用于 Windows 和 Linux 平台的强大功能。

GoogleTest UI是一个测试运行器,它运行您的测试二进制文件,允许您通过进度条跟踪其进度,并显示测试失败列表。单击一个显示失败文本。GoogleTest UI 是用 C# 编写的。

GTest TAP ListenerGoogleTest的一个事件监听器,它实现了测试结果输出的 TAP 协议。如果您的测试运行器了解 TAP,您可能会发现它很有用。

gtest-parallel是一个测试运行器,它并行运行来自二进制文件的测试以提供显着的加速。

GoogleTest Adapter是一个 VS Code 扩展,允许在树视图中查看 GoogleTest,并运行/调试您的测试。

C++ TestMate是一个 VS Code 扩展,允许在树视图中查看 GoogleTest,并运行/调试您的测试。

Cornichon是一个小型 Gherkin DSL 解析器,可为 GoogleTest 生成存根代码。

googletest的下载与编译

github链接:https://github.com/google/googletest

cmake gui编译

添加代码路径和生成后的目录,点击configure, 我编译的是win32版本

增加一个编译选项 CMAKE_DEBUG_POSTFIX,类型为STRING, value为 _d(这个随便写,只是为了区分debug和release的

库)这样编译后的debug库就会自带一个d后缀,与release的好区分。

点击generate

出现以上结果表示sln生成ok, 点击open project即可打开项目,一共66个子项目,其中有lib和googletest的测试代码。

右键INSTALL项目,生成解决方案,即可把.h .lib .dll 提取到cmake编译时设置的CMAKE_INSTALL_PREFIX目录里,我的生成结果:

bin目录里是dll

很多项目都可以用cmake进行编译,只要在源码根目录看到了CMakeLists.txt, 那么这种项目就可以使用cmake进行编译,比如:

  • VTK
  • OpenCV
  • jsoncpp
  • log4cplus
  • googletest
  • google chromium
  • webrtc
  • glog
  • 还有很多 。。。

在vs2019中使用googletest

一般编译后,都是.h .lib .dll, 在vs中进行配置就可以使用,下面是gtest的测试代码:

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

#pragma comment(lib, "gtestd.lib")

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

//编写测试case
TEST(testCase, test0)
{
    EXPECT_EQ(add(2, 3), 5);   //判断结果是不是等于5,EXPECT_EQ表示 "等于"
}

int main(int argc, char** argv)
{
    testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}

运行结果

GTest的一些基本概念

要测试一个类或函数,我们需要对其行为做出断言。当一个断言失败时,Google Test会在屏幕上输出该代码所在的源文件及其所在的位置行号,以及错误信息。也可以在编写断言时,提供一个自定义的错误信息,这个信息在失败时会被附加在Google Test的错误信息之后。

断言常常成对出现,它们都测试同一个类或者函数,但对当前功能有着不同的效果。ASSERT_*版本的断言失败时会产生致命失败,并结束当前函数。EXPECT_*版本的断言产生非致命失败,而不会中止当前函数。通常更推荐使用EXPECT_*断言,因为它们运行一个测试中可以有不止一个的错误被报告出来。但如果在编写断言如果失败,就没有必要继续往下执行的测试时,你应该使用ASSERT_*断言。 因为失败的ASSERT_*断言会立刻从当前的函数返回,可能会跳过其后的一些的清洁代码,这样也许会导致空间泄漏。

GTest的断言

1、布尔值检查

Fatal assertion Nonfatal assertion Verifies
ASSERT_TRUE(condition); EXPECT_TRUE(condition); condition is true
ASSERT_FALSE(condition); EXPECT_FALSE(condition); condition is false

2、数值型数据检查

Fatal assertion Nonfatal assertion Verifies
ASSERT_EQ(expected, actual); EXPECT_EQ(expected, actual); expected == actual
ASSERT_NE(val1, val2); EXPECT_NE(val1, val2); val1 != val2
ASSERT_LT(val1, val2); EXPECT_LT(val1, val2); val1 < val2
ASSERT_LE(val1, val2); EXPECT_LE(val1, val2); val1 <= val2
ASSERT_GT(val1, val2); EXPECT_GT(val1, val2); val1 > val2
ASSERT_GE(val1, val2); EXPECT_GE(val1, val2); val1 >= val2

3、字符串比较

Fatal assertion Nonfatal assertion Verifies
ASSERT_STREQ(expected_str, actual_str); EXPECT_STREQ(expected_str, actual_str); 两个C字符串有相同的内容
ASSERT_STRNE(str1, str2); EXPECT_STRNE(str1, str2); 两个C字符串有不同的内容
ASSERT_STRCASEEQ(expected_str, actual_str); EXPECT_STRCASEEQ(expected_str, actual_str); 两个C字符串有相同的内容,忽略大小写
ASSERT_STRCASENE(str1, str2); EXPECT_STRCASENE(str1, str2); 两个C字符串有不同的内容,忽略大小写

4、异常检查

Fatal assertion Nonfatal assertion Verifies
ASSERT_THROW(statement, exception_type); EXPECT_THROW(statement, exception_type); statement throws an exception of the given type
ASSERT_ANY_THROW(statement); EXPECT_ANY_THROW(statement); statement throws an exception of any type
ASSERT_NO_THROW(statement); EXPECT_NO_THROW(statement); statement doesn't throw any exception

5、浮点型检查

Fatal assertion Nonfatal assertion Verifies
ASSERT_FLOAT_EQ(expected, actual); EXPECT_FLOAT_EQ(expected, actual); the two float values are almost equal
ASSERT_DOUBLE_EQ(expected, actual); EXPECT_DOUBLE_EQ(expected, actual); the two double values are almost equal

对相近的两个数比较:

Fatal assertion Nonfatal assertion Verifies
ASSERT_NEAR(val1, val2, abs_error); EXPECT_NEAR*(val1, val2, abs_error*); the difference between val1 and val2 doesn't exceed the given absolute error

6、此外还有类型检查、谓词检查等

事件机制

全局事件

要实现全局事件,必须写一个类,继承testing::Environment类,实现里面的SetUp和TearDown方法。

  1. SetUp()方法在所有案例执行前执行
  2. TearDown()方法在所有案例执行后执行

还需要告诉gtest添加这个全局事件,我们需要在main函数中通过testing::AddGlobalTestEnvironment方法将事件挂进来,也就是说,我们可以写很多个这样的类,然后将他们的事件都挂上去。

TestSuite事件

我们需要写一个类,继承testing::Test,然后实现两个静态方法

  1. SetUpTestCase() 方法在第一个TestCase之前执行
  2. TearDownTestCase() 方法在最后一个TestCase之后执行

在编写测试案例时,我们需要使用TEST_F这个宏,第一个参数必须是我们上面类的名字,代表一个TestSuite。

TestCase事件

TestCase事件是挂在每个案例执行前后的,实现方式和上面的几乎一样,不过需要实现的是SetUp方法和TearDown方法:

  1. SetUp()方法在每个TestCase之前执行
  2. TearDown()方法在每个TestCase之后执行

以下案例解决说明上述三个事件的使用

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

#pragma comment(lib, "gtestd.lib")

using namespace std;

class Student
{
public:
    Student()
    {
        age = 0;
    }

    Student(int a)
    {
        age = a;
    }

    void print()
    {
        cout << "*********** " << age << " **********" << endl;;
    }

private:
    int age;
};

class FooEnvironment : public testing::Environment
{
public:
    virtual void SetUp()
    {
        std::cout << "Foo FooEnvironment SetUP" << std::endl;
    }

    virtual void TearDown()
    {
        std::cout << "Foo FooEnvironment TearDown" << std::endl;
    }
};

static Student* s;

//在第一个test之前,最后一个test之后调用SetUpTestCase()和TearDownTestCase()
class TestMap :public testing::Test
{
public:
    static void SetUpTestCase()
    {
        cout << "SetUpTestCase()" << endl;
        s = new Student(23);
    }

    static void TearDownTestCase()
    {
        delete s;
        cout << "TearDownTestCase()" << endl;
    }

    void SetUp()
    {
        cout << "SetUp() is running" << endl;

    }

    void TearDown()
    {
        cout << "TearDown()" << endl;
    }
};

TEST_F(TestMap, Test1)
{
    // you can refer to s here
    s->print();
}

int main(int argc, char** argv)
{
    testing::AddGlobalTestEnvironment(new FooEnvironment);
    testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}

运行结果

参数化

​ 当考虑多次要为被测函数传入不同的值的情况时,可以按下面的方式去测试。必须添加一个类,继承testing::TestWithParam。其中T就是你需要参数化的参数类型,如下面的案例是int型参数。(官方文档上的案例)

#include<gtest/gtest.h>
// Returns true iff n is a prime number.
bool IsPrime(int n)
{
    // Trivial case 1: small numbers
    if (n <= 1) return false;
    // Trivial case 2: even numbers
    if (n % 2 == 0) return n == 2;
    // Now, we have that n is odd and n >= 3.
    // Try to divide n by every odd number i, starting from 3
    for (int i = 3; ; i += 2) {
        // We only have to try i up to the squre root of n
        if (i > n/i) break;
        // Now, we have i <= n/i < n.
        // If n is divisible by i, n is not prime.
        if (n % i == 0) return false;
    }
    // n has no integer factor in the range (1, n), and thus is prime.
    return true;
}

class IsPrimeParamTest : public::testing::TestWithParam<int>{};
TEST_P(IsPrimeParamTest, HandleTrueReturn)
{
 int n =  GetParam();
 EXPECT_TRUE(IsPrime(n));
}
//被测函数须传入多个相关的值
INSTANTIATE_TEST_CASE_P(TrueReturn, IsPrimeParamTest, testing::Values(3, 5, 11, 23, 17));
int main(int argc, char **argv)
{
    testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}

gtest的使用就介绍这么多,大家有兴趣的话,可以加到自己的C++项目中做代码测试。

到此这篇关于google c++程序测试框架googletest使用教程的文章就介绍到这了,更多相关c++程序测试框架googletest内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • C++while和do-while语句求和详解

    目录 while语句求和 小结: do-while语句求和 代码如下. 总结 while语句求和 while的语言结构简洁,当符合循环条件(表达式)时,系统将执行循环体(语句).执行过程如图所示: 接下来我们将通过实例来熟悉while语句. 实例:利用while语句实现输入5名学生成绩并求和. 思路:构建循环体和循环语句. 循环体:输入数据并求和: 循环语句:不到五次时,继续循环. 代码如下. #include<iostream> using namespace std; int main()

  • c++基础学习之如何区分引用和指针

    目录 前言 1.引用 1.1引用的概念 1.2引用的定义 1.3引用与const 1.4引用的使用场景 2.指针 2.1概念 2.2获取对象的地址 2.3利用指针访问对象 2.3空指针 2.4野指针 2.4.1概念: 2.4.2野指针的产生: 2.5各个指针类型的含义 2.6 void* 指针 2.7指向指针的指针 2.8指针与const 3.指针和引用的区别 总结 前言 对于我刚学c++的时候,最令我头疼的是引用和指针,老是区分不了它们,那么今天笔者将我的学习到的笔记总结出来,让大家少走一些坑

  • 神奇的c/c++小游戏((提高你的编程兴趣)

    目录 神奇的c/c++ 神奇的c/c++ 以下代码在Dev,codeblocks,VC上都能运行 #include<stdio.h> #include<time.h> #include<stdlib.h> #include<conio.h> #include<windows.h> //下面Sleep()函数的头文件 #include<mmsystem.h> void menu() { printf(" ***********

  • C++ ostream用法案例详解

    概述 在 C++中,ostream表示输出流,英文"output stream"的简称.在 C++中常见的输出流对象就是标准输出流cout,很少自定义ostream的对象,更多的是直接使用cout.那么 ostream 有什么用呢,来看一个场景: class CPoint { public: CPoint(int x_,int y_):x(x_),y(y_){} int x,y; }; 这里定义了一个简单的类CPoint,如果我们实例化该类过后,想要打印对象的值: CPoint poi

  • C++ GetDlgItem用法案例详解

    GetDlgItem的用法小结 GetDlgItem用于获得指定控件ID的窗体指针,函数原型如下: HWND GetDlgItem( HWND hDlg, int nIDDlgItem ); CWnd* GetDlgItem(int nID) const; 它的使用说明中有这样一行字,**The returned pointer may be temporary and should not be stored for later use. **,那说明,它返回的指针有可能是有效的,有可能是无效

  • C++实现控制台随机迷宫的示例代码

    我全程使用TCHAR系列函数,亲测可以不改动代码兼容Unicode/ANSI开发环境,功能正常.大概有100行代码是来自网络的,我也做了改动,侵权请联系删除. 这个代码不能算是完美,还是会有轻微的闪屏现象,懒得再加双缓存了,大家可以自行修改.这里用的是SetConsoleCursorPosition函数和cls刷新屏幕. 好了,上代码!VS2015编译通过无警告.其他版本应该也没问题 // C++ Maze main code // Copyright (c) 2020 szx0427 #inc

  • 带你粗略了解c++的最大乘积

    目录 今天给大家讲最大乘积这道题目 样例 思路 代码 总结 今天给大家讲最大乘积这道题目 最大乘积 内存限制:256 MiB 时间限制:1000 ms 输入文件:maximum.in 输出文件:maximum.out 题目类型:传统 评测方式:文本比较 题目描述 给你 n n n个整数 a 1 , a 2 , a 3 , a 4... a n a1,a2,a3,a4...an a1,a2,a3,a4...an 从中任意挑选出个数字,使得乘积最大,输出乘积最大值. 输入格式 输入有多组测试数据.

  • CreateCompatibleDC()函数案例详解

    函数功能:该函数创建一个与指定设备兼容的内存设备上下文环境(DC). 函数原型:HDC CreateCompatibleDC(HDC hdc): 参数: hdc:现有设备上下文环境的句柄,如果该句柄为NULL,该函数创建一个与应用程序的当前显示器兼容的内存设备上下文环境. 返回值:如果成功,则返回内存设备上下文环境的句柄:如果失败,则返回值为NULL. CreateCompatibleDc函数只适用于支持光栅操作的设备,应用程序可以通过调用GetDeviceCaps函数来确定一个设备是否支持这些

  • google c++程序测试框架googletest使用教程详解

    目录 什么是googletest? googletest简介 谁在使用 GoogleTest? 相关开源项目 googletest的下载与编译 cmake gui编译 在vs2019中使用googletest GTest的一些基本概念 GTest的断言 事件机制 参数化 什么是googletest? googletest简介 ​GoogleTest 是 Google 的 C++ 测试和模拟框架,可以帮助程序员测试C++程序的结果预期,GoogleTest 的代码用cmake管理,可以使用cmak

  • Node.js中Express框架的使用教程详解

    目录 Express简介 Express生成器 1. 什么是Express生成器 2. 安装Express生成器 创建Express项目 安装项目依赖 运行Express项目 Express目录结构说明 创建一个新路由模块 1. 创建ejs模块文件 2. 创建路由文件 3. 在app.js中引入路由 4. 运行项目 经过前面几天对Node.js的学习,基本的开发知识已经逐渐掌握,所谓工欲善其事必先利其器,今天进一步学习Node.js的开发框架Express.利用Express框架可以快速的进行W

  • Bootstrap框架的学习教程详解(二)

    Bootstrap,来自 Twitter,是目前最受欢迎的前端框架.Bootstrap 是基于 HTML.CSS.JAVASCRIPT 的,它简洁灵活,使得 Web 开发更加快捷. 一.下载Bootstrap Bootstrap (当前版本 v3.3.0)提供以下几种方式帮你快速上手,每一种方式针对具有不同技能等级的开发者和不同的使用场景. 下载地址:http://v3.bootcss.com/getting-started/#download PS:其实我们不用下载bootstrap也可以使用

  • 基于Python的接口自动化unittest测试框架和ddt数据驱动详解

    引言 在编写接口自动化用例时,我们一般针对一个接口建立一个.py文件,一条接口测试用例封装为一个函数(方法),但是在批量执行的过程中,如果其中一条出错,后面的用例就无法执行,还有在运行大量的接口测试用例时测试数据如何管理和加载.针对测试用例加载以及执行控制,python语言提供了unittest单元测试框架,将测试用例编写在unittest框架下,使用该框架可以单个或者批量加载互不影响的用例执行及更灵活的执行控制,对于更好的进行测试数据的管理和加载,这里我们引入数据驱动的模块:ddt,测试数据和

  • Pytest测试框架基本使用方法详解

    pytest介绍 pytest是一个非常成熟的全功能的Python测试框架,主要特点有以下几点: 1.简单灵活,容易上手,文档丰富: 2.支持参数化,可以细粒度地控制要测试的测试用例: 3.能够支持简单的单元测试和复杂的功能测试,还可以用来做selenium/appnium等自动化测试.接口自动化测试(pytest+requests); 4.pytest具有很多第三方插件,并且可以自定义扩展 如pytest-selenium(集成selenium). pytest-html(完美html测试报告

  • python Web应用程序测试selenium库使用用法详解

    目录 一.声明浏览器对象 二.访问页面并获取网页html 三.查找元素 四.元素交互操作-搜索框传入关键词进行自动搜索 五.交互动作,驱动浏览器进行动作,模拟拖拽动作,将动作附加到动作链中串行执行 六.执行JavaScript 七.获取元素信息 八.Frame操作 九.等待 十一.前进后退-实现浏览器的前进后退以浏览不同的网页 十二.Cookies 十三.异常处理 模拟浏览器进行网页加载,当requests,urllib无法正常获取网页内容的时候 一.声明浏览器对象 注意点一,Python文件名

  • C++ 测试框架GoogleTest入门介绍

    目录 引言 简单介绍 初体验 引言 开发者虽然主要负责工程里的开发任务,但是每个开发完毕的功能都是需要开发者自测通过的,所以经常会听到开发者提起单元测试的话题.那么今天我就带大伙一起来看看大名鼎鼎的谷歌 C++ 测试框架 GoogleTest. 简单介绍 来看看谷歌官方是怎么介绍这个框架的: Googletest 是由测试技术团队根据 Google 的特定要求和约束开发的测试框架.无论您是在 Linux,Windows 还是 Mac 上工作,如果您编写 C++ 代码,googletest 都可以

  • 基于mpvue搭建微信小程序项目框架的教程详解

    简介: mpvue框架对于从没有接触过小程序又要尝试小程序开发的人员来说,无疑是目前最好的选择.mpvue从底层支持 Vue.js 语法和构建工具体系,同时再结合相关UI组件库,便可以高效的实现小程序开发 前言: 本文讲述如何搭建完整的小程序项目框架,因为是第一次使用,有不完善的地方请大佬指正. 搭建内容包括: 1.使用scss语法:依赖插件sass-loader .node-sass 2.像vue一样使用路由:依赖插件 mpvue-entry 和 mpvue-router-patch 3.使用

  • Python ORM数据库框架Sqlalchemy的使用教程详解

    目录 概念和数据类型 安装 连接 创建数据库表类(模型) 生成数据库表 会话 增删改查 增 查 改 删 执行裸sql with关闭会话 sql建造者模式 封装的工具 数据库配置文件database.properties 工具 测试实体 验证代码 对象关系映射(Object Relational Mapping,简称ORM)模式是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术.面向对象的开发方法是当今企业级应用开发环境中的主流开发方法,关系数据库是企业级应用环境中永久存放数据的主流数据

  • IDEA版最新MyBatis程序配置教程详解

    实验环境:IDEA2020.1+MySQL8.0.21+Mybatis3.5.5+Junit4.13 搭建环境–>导入Mybatis->编写代码->测试 1.搭建实验数据库 我们创建一个mybatis实验数据库,并创建一个user表为后续实验准备 CREATE DATABASE `mybatis`; USE `mybatis`; CREATE TABLE `user`( `id` INT(4) NOT NULL PRIMARY key, `name` VARCHAR(20) NOT NU

随机推荐