GTest学习笔记(七)

2023-11-15

参考博客: Advanced googletest Topics | GoogleTest

前言:参数化测试允许对代码进行多种输入的测试,而不需要复制很多相同的代码。本文主要介绍GTest的参数化测试的适用环境、编写方式以及参数化的抽象测试

1 参数化测试的适用环境

  • 你有一段代码,它的行为受一个或多个命令行标志的影响 。你想要确保在这些标志在取各种各样的值的时候,代码的表现都是正常的
  • 你想要测试一个OO(面向对象的)接口的多种实现
  • 你现在各种各样的输入上测试你的代码(又称数据驱动的)。 这个功能很容易被滥用,所以在使用的时候请锻炼你的判断力!

2 如何写参数化测试

  • 首先要定义一个固件类

    它必须同时继承 testing::Test类和testing::WithParamInterface<T> 类,其中T就是你要测试的参数的类别。为了方便起见,你可以直接继承testing::TestWithParam<T>类,这个类自身是同时继承 testing::Test类和testing::WithParamInterface<T> 类的。T可以是任意一个可拷贝的类型。如果T是一个原始指针,你需要对对管理这个指针指向的值的生命周期负责。

    注意,如果固件类中定义了SetUpTestSuite()TearDownTestSuite(),那么这两个函数必须要声明为公共的而不是受保护的,这样才可以使用TEST_P

    class FooTest :
        public testing::TestWithParam<const char*> {
      // You can implement all the usual fixture class members here.
      // To access the test parameter, call GetParam() from class
      // TestWithParam<T>.
    };
    
    // Or, when you want to add parameters to a pre-existing fixture class:
    class BaseTest : public testing::Test {
      ...
    };
    class BarTest : public BaseTest,
                    public testing::WithParamInterface<const char*> {
      ...
    };
    
  • 接着用宏TEST_P定义测试函数

    TEST_P(FooTest, DoesBlah) {
      // Inside a test, access the test parameter with the GetParam() method
      // of the TestWithParam<T> class:
      EXPECT_TRUE(foo.Blah(GetParam()));
      ...
    }
    
    TEST_P(FooTest, HasBlahBlah) {
      ...
    }
    
  • 最后用宏INSTANTIATE_TEST_SUITE_P来实例化这个test suite

    在宏INSTANTIATE_TEST_SUITE_P中可以传入任何你想要的参数集合,宏中第一个参数是这个test suite的实例的名字,第二个参数是固件类的类名,最后一个参数就是代码生成器。

    INSTANTIATE_TEST_SUITE_P(MeenyMinyMoe,
                             FooTest,
                             testing::Values("meeny", "miny", "moe"));
                             
    // 也可以
    const char* pets[] = {"cat", "dog"};
    INSTANTIATE_TEST_SUITE_P(Pets, FooTest, testing::ValuesIn(pets));                        
    
  • 示例

    #include "stdio.h"
    #include "gtest/gtest.h"
    bool isEven(int a)
    {
        int result;
        result = a % 2;
        if (result == 0)
            return true;
        else
            return false;
    }
    class NumIsEven : public::testing::TestWithParam<int> {
    public:
        NumIsEven() {
            printf("NumIsEven类构造函数执行!\n");
        }
    
        ~NumIsEven() override {
            printf("NumIsEven类析构函数执行!\n");
        }
    };
    
    TEST_P(NumIsEven, TestEven1) {
    
        EXPECT_TRUE(isEven(GetParam()));
    }
    
    TEST_P(NumIsEven, TestEven2) {
        EXPECT_EQ(isEven(GetParam()), true);
    }
    
    INSTANTIATE_TEST_SUITE_P(EvenNumberTest1, NumIsEven, testing::Values(21, 221, 1001));
    
    int pets[] = { 35, 42 };
    INSTANTIATE_TEST_SUITE_P(EvenNumberTest2, NumIsEven, testing::ValuesIn(pets));
    
    int main(int argc, char** argv) {
        ::testing::InitGoogleTest(&argc, argv);
        return RUN_ALL_TESTS();
    }
    

在这里插入图片描述

3 创建参数化的抽象测试

有时你或许想要在库中定义参数化的测试函数,然后让其他人后续再实例化它。这种模式就称为抽象测试,具体的操作如下:

  • 在一个头文件abstract_test.h中定义测试固件类,把这个操作想象成对抽象测试的声明
  • 在一个源文件(头文件包含abstract_test.h)中定义TEST_P函数,把这个操作想象成抽象测试的实现

定义完成后就可以通过包含头文件的方式来实例化它,调用INSTANTIATE_TEST_SUITE_P(),依赖包含源文件的目标库

内容如有错误,敬请指正!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

GTest学习笔记(七) 的相关文章

  • OpenCv读/写视频色差

    我试图简单地使用 openCV 打开视频 处理帧并将处理后的帧写入新的视频文件 我的问题是 即使我根本不处理帧 只是打开视频 使用 VideoCapture 读取帧并使用 VideoWriter 将它们写入新文件 输出文件看起来比输入更 绿
  • 如何创建可以像 UserControl 一样编辑的 TabPage 子类?

    我想创建一个包含一些控件的 TabPage 子类 并且我想通过设计器来控制这些控件的布局和属性 但是 如果我在设计器中打开子类 我将无法像在 UserControl 上那样定位它们 我不想创建一个带有 UserControl 实例的 Tab
  • 如何在 Android NDK 中创建新的 NativeWindow 而无需 Android 操作系统源代码?

    我想编译一个 Android OpenGL 控制台应用程序 您可以直接从控制台启动 Android x86 运行 或者从 Android x86 GUI 内的 Android 终端应用程序运行 这个帖子 如何在 Android NDK 中创
  • 为什么要序列化对象需要 Serialized 属性

    根据我的理解 SerializedAttribute 不提供编译时检查 因为它都是在运行时完成的 如果是这样 那么为什么需要将类标记为可序列化呢 难道序列化器不能尝试序列化一个对象然后失败吗 这不就是它现在所做的吗 当某些东西被标记时 它会
  • C++:重写已弃用的虚拟方法时出现弃用警告

    我有一个纯虚拟类 它有一个纯虚拟方法 应该是const 但不幸的是不是 该接口位于库中 并且该类由单独项目中的其他几个类继承 我正在尝试使用这个方法const不会破坏兼容性 至少在一段时间内 但我找不到在非常量方法重载时产生警告的方法 以下
  • 构造函数中显式关键字的使用

    我试图了解 C 中显式关键字的用法 并查看了这个问题C 中的explicit关键字是什么意思 https stackoverflow com questions 121162 但是 那里列出的示例 实际上是前两个答案 对于用法并不是很清楚
  • JSON 数组到 C# 列表

    如何将这个简单的 JSON 字符串反序列化为 C 中的列表 on4ThnU7 n71YZYVKD CVfSpM2W 10kQotV 这样 List
  • 暂停下载线程

    我正在用 C 编写一个非常简单的批量下载程序 该程序读取要下载的 URL 的 txt 文件 我已经设置了一个全局线程和委托来更新 GUI 按下 开始 按钮即可创建并启动该线程 我想要做的是有一个 暂停 按钮 使我能够暂停下载 直到点击 恢复
  • 如何从网站下载 .EXE 文件?

    我正在编写一个应用程序 需要从网站下载 exe 文件 我正在使用 Visual Studio Express 2008 我正在使用以下代码 private void button1 Click object sender EventArgs
  • Qt 创建布局并动态添加小部件到布局

    我正在尝试在 MainWindow 类中动态创建布局 我有四个框架 它们是用网格布局对象放置的 每个框架都包含一个自定义的 ClockWidget 我希望 ClockWidget 对象在调整主窗口大小时相应地调整大小 因此我需要将它们添加到
  • 在非活动联合成员上使用“std::addressof”是否定义明确[重复]

    这个问题在这里已经有答案了 下面的代码是尝试实现constexpr的版本offsetof在 C 11 中 它可以在 gcc 7 2 0 和 clang 5 0 0 中编译 这取决于申请std addressof工会非活跃成员的成员 这是明确
  • C# 中条件编译符号的编译时检查(参见示例)?

    在 C C 中你可以这样做 define IN USE 1 define NOT IN USE 1 define USING system 1 system 1 IN USE 进而 define MY SYSTEM IN USE if US
  • 为什么我不应该对不是由 malloc() 分配的变量调用 free() ?

    我在某处读到 使用它是灾难性的free删除不是通过调用创建的对象malloc 这是真的 为什么 这是未定义的行为 永远不要尝试它 让我们看看当您尝试时会发生什么free 自动变量 堆管理器必须推断出如何获取内存块的所有权 为此 它要么必须使
  • 如何一步步遍历目录树?

    我发现了很多关于遍历目录树的示例 但我需要一些不同的东西 我需要一个带有某种方法的类 每次调用都会从目录返回一个文件 并逐渐遍历目录树 请问我该怎么做 我正在使用函数 FindFirstFile FindNextFile 和 FindClo
  • 耐用功能是否适合大量活动?

    我有一个场景 需要计算 500k 活动 都是小算盘 由于限制 我只能同时计算 30 个 想象一下下面的简单示例 FunctionName Crawl public static async Task
  • 当前的 x86 架构是否支持非临时加载(来自“正常”内存)?

    我知道有关此主题的多个问题 但是 我没有看到任何明确的答案或任何基准测量 因此 我创建了一个处理两个整数数组的简单程序 第一个数组a非常大 64 MB 第二个数组b很小 无法放入 L1 缓存 程序迭代a并将其元素添加到相应的元素中b在模块化
  • strcmp 给出分段错误[重复]

    这个问题在这里已经有答案了 这是我的代码给出分段错误 include
  • WinRT 定时注销

    我正在开发一个 WinRT 应用程序 要求之一是应用程序应具有 定时注销 功能 这意味着在任何屏幕上 如果应用程序空闲了 10 分钟 应用程序应该注销并导航回主屏幕 显然 执行此操作的强力方法是在每个页面的每个网格上连接指针按下事件 并在触
  • 匿名结构体作为返回类型

    下面的代码编译得很好VC 19 00 23506 http rextester com GMUP11493 标志 Wall WX Za 与VC 19 10 25109 0 标志 Wall WX Za permissive 这可以在以下位置检
  • 错误:无效使用不完整类型“类 Move”/未定义对 Move::NONE 的引用

    拜托 我不知道为什么这个简单的代码被拒绝 它给了我 2 个编译错误 请帮帮我 I use 代码 块 20 03 我的编译器是GNU GCC 移动 hpp class Move public Move Move int int public

随机推荐

  • 题目 1162: 密码

    网上流传一句话 常在网上飘啊 哪能不挨刀啊 其实要想能安安心心地上网其实也不难 学点安全知识就可以 首先 我们就要设置一个安全的密码 那什么样的密码才叫安全的呢 一般来说一个比较安全的密码至少应该满足下面两个条件 1 密码长度大于等于8 且
  • SpringCloud Netflix Hystrix

    文章目录 一 Hystrix简介 1 什么是灾难性雪崩效应 2 什么是Hystrix 二 服务降级 Ribbon中 三 服务熔断 Ribbon中 服务降级的强化版 四 请求缓存 Ribbon中 不推荐 查询频率高 修改频率低时谨慎使用 五
  • syncthing数据同步应用-docker部署

    syncthing应用场景类似于rsync 在数据传输通道的两端都部署服务 再通过密钥验证的方式完成最终数据同步 而syncthing较之更加简单 因配备了Web UI 配置上难度降低了不少 相关资料 https syncthing net
  • go语言命令行库的安装与使用 -- cobra

    文章目录 前言 一 go env的配置 镜像源的设置 GOPROXY 二 cobra的安装与cobra cli的安装 1 cobra的安装 1 测试是否安装成功 2 cobra cli的安装 cobra cli的使用 前言 看了许多cobr
  • Vue3.0+ts—watch使用

    引入Vue的对象 ref reactive watch ref 用来声明响应式的基础类型的变量 reactive用来声明响应式的对象类型的变量 watch 引入watch对象 以便调用 import ref reactive watch f
  • 若依框架添加页面步骤

    本文代码使用的是ruoyi分离版 http doc ruoyi vip ruoyi vue 一 导入表 1 1查看数据库表 1 2使用后台代码生成模块 二 编辑表信息 若依框架前后端分离版本自动生成代码的详细步骤 1 若依框架的下载和本地运
  • Java Web-servlet技术-通过表单向servlet提交数据

    通过表单向servlet提交数据 1 创建名为ComputeBill的servlet文件 2 重写init 和service package myservlet import java io IOException import java
  • 游戏服务器维护请更换服务器,更换游戏服务器

    更换游戏服务器 内容精选 换一换 支持 您可以先将弹性公网IP从原弹性云服务器解绑 如何解绑请参考解绑定和释放弹性公网IP 再将弹性公网IP绑定到目标弹性云服务器 如何绑定请参考绑定云资源 相关操作 为弹性云服务器更换绑定的弹性公网IP 请
  • Tomcat官网地址

    Tomcat官网地址 https tomcat apache org https tomcat apache org
  • 《再也不怕elasticsearch》es聚合使用与原理剖析

    大家好我是迷途 一个在互联网行业 摸爬滚打的学子 热爱学习 热爱代码 热爱技术 热爱互联网的一切 再也不怕elasticsearch系列 帅途会慢慢由浅入深 为大家剖析一遍 各位大佬请放心 虽然这个系列帅途有时候更新的有点慢 但是绝对不会烂
  • 去除 Zotero + Obsidian 复制粘贴参考文献表时的多余空行(ctrl+shift+C)

    前言 最近在用 Zotero 做文献管理 用 Obsidian 记笔记 但是使用的时候 有一个问题不大 但是有时候很烦人的情况 粘贴参考文献格式 在粘贴的时候总会莫名多出来几个空行 需要手动删除 举个例子 下面是某个文献库 我希望将第一篇文
  • 广告营销用户点击预测分析

    广告营销用户点击预测分析 零 数据集以及数据集简介以及任务分析 一 数据预处理 1 加载检查数据 1 特殊特征 2 特殊特征的处理 3 特殊特征处理后生成的新特征 2 数据类型与缺失值处理 1 查看数据信息 2 数据补全以及类型转换 3 补
  • 为什么 Thread 类的 sleep() 和 yield () 方法是静态方法?(详解)

    首先明确一点 在一个线程拿到锁的时候 其他线程向拿到锁就必须要等待 author FanQie date 2022 7 30 10 43 public class SleepYield private static Object resou
  • docker 运行pytorch 程序报错---ERROR: Unexpected bus error encountered in worker.

    1 错误 ERROR Unexpected bus error encountered in worker This might be caused by insufficient shared memory shm 2 原因 Pytorc
  • springboot项目部署云服务器,SpringBoot项目的云服务器部署

    1 场景还原 springboot配置相当简单 人人皆知 怎么把springboot工程部署到云服务器上呢 可能有人会说 博主你前篇不是讲了java工程的云部署把 但是我想澄清一点的是 我前篇的工程都是ssm框架搭建的 而springboo
  • 20个免费视频素材平台推荐

    视频剪辑大神的视频素材是从哪里找的 视频素材不知道去哪里找 那可以看看本文 本文总结了素材的方方面面 包括图片 图标以及视频音频的素材网站整理 再也无需为视频素材烦恼 1 新CG儿 一个特别良心的素材网站 模板和视频都非常丰富 重要的是基本
  • 蓝桥杯精选赛题算法系列——迷宫——DFS

    已收录此专栏 今天我们会全面学习 DFS 的相关知识 包括理论 模板 真题等 深度优先搜索 DFS Depth First Search 和宽度优先搜索 BFS Breadth First Search 或称为广度优先搜索 是基本的暴力技术
  • Apache Flink不止于计算,数仓架构或兴起新一轮变革

    2021 年初 在 InfoQ 编辑部策划的全年技术趋势展望中 我们提到大数据领域将加速拥抱 融合 或 一体化 演进的新方向 本质是为了降低大数据分析的技术复杂度和成本 同时满足对性能和易用性的更高要求 如今 我们看到流行的流处理引擎 Ap
  • electron globalShortcut 快捷键与系统全局快捷键冲突

    用 electron 开发自己的接口测试工具 Post Tools 在设置了 globalShortcut 快捷键后 发现应用中的快捷键与系统全局快捷键冲突了 导致系统快捷键不可正常使用 快捷键配置 export function init
  • GTest学习笔记(七)

    参考博客 Advanced googletest Topics GoogleTest 前言 参数化测试允许对代码进行多种输入的测试 而不需要复制很多相同的代码 本文主要介绍GTest的参数化测试的适用环境 编写方式以及参数化的抽象测试 1