gtest之高级主题

目录

  • Value-Parameterized测试
    • 示例
    • Value-Parameterized实现
  • 类型测试
  • Type-Parameterized Tests
  • 注册test程序
  • 获取当前测试程序名
  • 运行测试程序选项
    • 选择性测试
    • 重复测试
    • 无序执行
    • 分发到不同的机器
    • 控制输出
    • Controlling How Failures Are Reported
    • 结合Sanitizer

Value-Parameterized测试

示例

先看测试代码,需要验证以下三个函数的返回值和1,2,3做对比

int test_p_func1() {
    return 1;
}

int test_p_func2() {
    return 2;
}

int test_p_func3() {
    return 3;
}

TEST 这样写

TEST(TestPFuncSuite, TestPFunc1) {
    EXPECT_EQ(test_p_func1(), 1);
    EXPECT_EQ(test_p_func1(), 2);
    EXPECT_EQ(test_p_func1(), 3);
    EXPECT_EQ(test_p_func2(), 1);
    EXPECT_EQ(test_p_func2(), 2);
    EXPECT_EQ(test_p_func2(), 3);
    EXPECT_EQ(test_p_func3(), 1);
    EXPECT_EQ(test_p_func3(), 2);
    EXPECT_EQ(test_p_func3(), 3);
}

这里因为不同的输入(要测试的接口)分别写了EXPECT_EQ,造成代码冗余,为避免这种情况,可以使用Value-parameterized tests。Value-parameterized tests可以通过不同的参数测试功能,避免因为不同的参数而要拷贝多个test body。用Value-parameterized tests可以按如下实现

class TableTestSample1 : public ::testing::TestWithParam<std::function<int()>>
{
public:
    void SetUp() override {
        std::function<int()> f = GetParam();
        val_ = f();
    }

protected:
    int val_;
};

TEST_P(TableTestSample1, aaa) {
    EXPECT_EQ(1, val_);
    EXPECT_EQ(2, val_);
    EXPECT_EQ(3, val_);
}

INSTANTIATE_TEST_SUITE_P(MyTestPCase1, TableTestSample1, ::testing::Values(&test_p_func1, &test_p_func2, &test_p_func3));

如果test_p_func1带参数,可以通过std::bind将函数对象返回:::testing::Values(std::bind(&test_p_func1, param1, param2));

Value-Parameterized实现

分三步

  • 实现一个fixture类,这个类必须要继承自testing::Test 和 testing::WithParamInterface,为简便起见,可以直接派生自testing::TestWithParam(testing::TestWithParam派生自testing::Test 和 testing::WithParamInterface)。注意:
    • T可以是任意可以拷贝的类型;
    • 如果T是一个裸指针类型,需要对其生命周期管理。
  • 使用TEST_P宏定义
  • 使用INSTANTIATE_TEST_SUITE_P 宏通过你指定的一系列参数实例化这个test suite

类型测试

假设相同的接口,有不同的实现,想要确保他们满足相同的要求;或者定义了不同的类型,但是它们有着相同的概念(啥意思?)要想验证,这两种情况下对不同的类型有着相同的测试逻辑,如果使用TEST 或者 TEST_F会显得相当冗长,此时可以使用typed tests。这里着重理解下不同的类型有相同的接口
实现步骤:

  1. 定义一个fixture模板类,继承自::testing::Test
  2. 关联测试套和要测试的一系列类型,注意这里的类型别名是有必要的
using MyTypes = ::testing::Types<char, int, unsigned int>;
TYPED_TEST_SUITE(FooTest, MyTypes);
  1. 使用TYPED_TEST()定义typed test suite
    测试代码
template<typename T>
class MyClass
{
public:
    MyClass() = default;
    MyClass(const T &t): val_(t) {

    }

    T get_param() {
        return val_;
    }

    bool get_name() const {
        return true;
    }

private:
    T val_;
};


template<typename T>
class MyFixture : public ::testing::Test
{
public:
    MyFixture() = default;
    void SetUp() override {

    }

protected:
    MyClass<T> p_;
};
using MyTypes = ::testing::Types<char, int, string>;
TYPED_TEST_SUITE(MyFixture, MyTypes);

TYPED_TEST(MyFixture, mytypedtest) {
    EXPECT_FALSE(this->p_.get_name());  // 注意,在test suite中要使用this访问Fixture中的变量
}

心得:TYPED_TEST中无法验证实现类型相关的接口信息?

Type-Parameterized Tests

类似于类型测试,但是不要求在测试之前就列出想要测试的类型。可以先写测试逻辑,然后再使用不同的类型实例化。可以在同一程序中多次实例化。
实现步骤:

  1. 定义fixture模板类,继承自::testing::Test
  2. 声明类型参数的test suite
  3. TYPED_TEST_P()实现
  4. 使用REGISTER_TYPED_TEST_SUITE_P 注册所有要测试的测试程序(第三步的实现),第一个参数是test suite名,其余名字为test name(即为3中的第二个参数)
  5. 实例化要测试的类型
using MyTypes = ::testing::Types<char, int, unsigned int>;
INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, MyTypes);

注册test程序

TODO

获取当前测试程序名

实际应用中可能需要知道当前运行的test name,可以通过类TestInfo来获取,要获取TestInfo对象,通过UnitTest单例的current_test_info()获取

  // Gets information about the currently running test.
  // 注意:不要删除获取到的这个对象,它由UnitTest 这个类管理
  const testing::TestInfo* const test_info =
      testing::UnitTest::GetInstance()->current_test_info();

  printf("We are in test %s of test suite %s.\n",
         test_info->name(),
         test_info->test_suite_name());

运行测试程序选项

可以通过环境变量或者命令行参数affect测试程序。为了支持命令行参数功能,必须在RUN_ALL_TESTS()之前调用::testing::InitGoogleTest()
可以通过在测试程序后加–help命令查看支持的选项
如果同时设置和环境变量和命令行参数命令,后者(命令行参数)将有优先权

选择性测试

  • –gtest_list_tests:显示出所有要测试的test suite和test name,但不会运行。这个命令可以方便查看编译出来的测试程序支持哪些test suite和test name。显示格式如下:在这里插入图片描述
  • gtest默认会运行所有的测试程序,如果只想运行其中的某一部分,可以设置环境变量 GTEST_FILTER 或者 命令行参数 --gtest_filter来设置过滤,gtest将会只运行名字符合过滤器的程序(格式为 TestSuiteName.TestName)。
    • ‘*’ 和 ‘?’ 通配符,匹配多个和一个
    • ‘:’ 表示或的关系,只要有一个的匹配都可以
    • ‘-’ 表示不匹配
./foo_test --gtest_filter=*Null*:*Constructor* Runs any test whose full name contains either "Null" or "Constructor" .
./foo_test --gtest_filter=-*DeathTest.* Runs all non-death tests.
./foo_test --gtest_filter=FooTest.*-FooTest.Bar Runs everything in test suite FooTest except FooTest.Bar.
./foo_test --gtest_filter=FooTest.*:BarTest.*-FooTest.Bar:BarTest.Foo Runs everything in test suite FooTest except FooTest.Bar and everything in test suite BarTest except BarTest.Foo.
  • –gtest_fail_fast:如果期望在第一次测试失败后,停止后面的测试,可以使用该选项
    在这里插入图片描述

  • 临时disable测试:如果有一些测试暂时不需要(有bug或者其他原因),使用注释或者预编译指令#if 0会让这些代码不被编译,可以在test suite名或者test name前加DISABLED_。(在test suite名或者test name前加效果一样)。

// Tests that Foo does Abc.
TEST(FooTest, DISABLED_DoesAbc) { ... }
class DISABLED_BarTest : public testing::Test { ... };
// Tests that Bar does Xyz.
TEST_F(DISABLED_BarTest, DoesXyz) { ... }

在这里插入图片描

  • 临时启用disable的测试:通过设置命令函参数–gtest_also_run_disabled_tests或者环境变量GTEST_ALSO_RUN_DISABLED_TESTS 为非0就可以将上面用DISABLE_ disable的test继续运行。

重复测试

偶现的问题可以通过重复多次测试复现,可以通过命令行参数 --gtest_repeat 或者环境变量 GTEST_REPEAT指定test methods运行多少次
–gtest_repeat=-1表示无限次执行
如果包含了global set-up/tear-down,也是会重复执行,为了避免重复执行全局set-up/tear-down,使用–gtest_recreate_environments_when_repeating=false

无序执行

测试套是按顺序执行的,如果想随机无须执行,可以指定命令行参数–gtest_shuffle或者环境变量GTEST_SHUFFLE
gtest会根据当前时间计算出随机种子数,会在控制台上输出。可以通过–gtest_random_seed=SEED或者GTEST_RANDOM_SEED 指定。随机种子数取值范围[0, 99999]。0代表gtest按默认当前时间计算seed值。如果将其与–gtest_repeat=N结合,GoogleTest将选择不同的随机种子,并在每次迭代中重新洗牌测试。

分发到不同的机器

控制输出

  • 通过带颜色的终端输出可以比较清晰的分辨信息,可以通过GTEST_COLOR 或者命令行参数–gtest_color,取值为yes,no,auto(默认值)使能颜色或由gtest决定。
  • 压缩测试结果:默认情况下一条测试会输出一条输出表明是否成功,通过命令行参数–gtest_brief=1或者将环境变量GTEST_BRIEF设置为1可以简化输出
    在这里插入图片描述
  • 禁止显示时间:more情况下会显示运行每条test花费了多长时间,通过命令行参数–gtest_print_time=0或者将GTEST_PRINT_TIME 设置为0禁止显示
  • Suppressing UTF-8 Text Output
  • 生成XML报告:通过将环境变量GTEST_OUTPUT 或者命令行参数 --gtest_output设置为"xml:path_to_output_file",会将xml文件生成在指定位置。也可以直接设置为"xml",会在当前目录下输出test_detail.xml。如果指定目录如"xml:output/directory/",会在指定目录下生成 测试程序名.xml,如果文件存在,为避免覆盖,googletest会选择一个不同的名字如 测试程序名_1.xml。
  • 生成json报告:同生成xml,通过将环境变量GTEST_OUTPUT 或者命令行参数 --gtest_output设置为"json:path_to_output_file",也可以直接设置为"json",会在当前目录下输出test_detail.json。

Controlling How Failures Are Reported

TODO

结合Sanitizer

TODO
Undefined Behavior Sanitizer:https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html
Address Sanitizer:https://github.com/google/sanitizers/wiki/AddressSanitizer
Thread Sanitizer:https://github.com/google/sanitizers/wiki/ThreadSanitizerCppManual

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/18241.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

MySQL读写分离

读写分离配置流程 master和slave机器的信息 IP地址&#xff1a; master&#xff08;centos7&#xff09;&#xff1a;192.168.131.129 slave&#xff08;win10&#xff09;&#xff1a;192.168.0.6 保证master和slave之间的网络互通&#xff0c;并且保证3306端口是开放的。 mas…

<IBM AIX><ERRPT><No.001>《出现E86653C3、49183216、8003764C告警的处理 20230506》

《出现E86653C3、49183216、8003764C告警的处理 20230506》 1 现象2 分析3 结论4 引申 1 现象 服务器出现errpt告警&#xff0c;告警为E86653C3、49183216、8003764C。 2 分析 1、hdisk1对应的VG&#xff0c;为rootvg。 lspv |grep hdisk12、查看VG状态 lsvg rootvg说明…

蓝牙耳机哪个品牌最好?数码博主整理2023超高性价比蓝牙耳机推荐

近来收到很多私信不知道蓝牙耳机哪个品牌最好&#xff0c;希望我能进行一期蓝牙耳机推荐&#xff0c;考虑到大家的预算不高&#xff0c;我特意花费时间测评了当下主流品牌的热销平价蓝牙耳机&#xff0c;最终整理成了这份超高性价比蓝牙耳机推荐&#xff0c;感兴趣的朋友们可以…

Spark学习笔记【shuffle】

本文基本上是大数据处理框架Apache Spark设计与实现的Shuffle部分的学习。以及Spark基础知识Bambrow Shuffle解决啥问题 上游和下游&#xff0c;不同stage&#xff0c;不同的task之间是如何传递数据的。ShuffleManager管理ShuffleWrite和ShuffleRead 分为两个阶段&#xff1…

系统安全分析与设计

目录 第五章、系统安全分析与设计1、信息系统安全属性2、对称加密技术与非对称加密技术3、信息摘要4、数字签名5、数字信封与PGP6、网络安全6.1、各个网络层次的安全保障6.2、网络威胁与攻击6.3、防火墙 第五章、系统安全分析与设计 1、信息系统安全属性 安全属性 保密性&…

Vivado 仿真器中以批处理或脚本模式(Batch or Scripted Mode)进行仿真

以下说明来自ug900:在 Vivado 仿真器中以批处理或脚本模式进行仿真 具体可以内容可自行查找 其中代码运行截图为自己实践的实例 Note: xelab, xvlog and xvhdl are not Tcl commands. The xvlog, xvhdl, xelab are Vivado-independent compiler executables. Hence, there is…

pyinstaller打包Mediapipe时遇到的问题

使用pyinstaller对python文件打包 打包流程 安装pyinstaller pip install pyinstaller打包文件 pyinstaller test.py 打包完成后会生成一个dist文件夹,打包的文件会在里面,找到test.exe。 pyinstaller -F test.py 加上-F会把所有的文件打包成一个exe,也是在dist文件夹下…

循环队列、双端队列

循环队列、双端队列 1. 循环队列1.1 循环队列1.2 代码实现1.3 力扣622. 设计循环队列2. 双端队列 1. 循环队列 1.1 循环队列 特殊的队列&#xff0c;首尾相连&#xff0c;空间可重复利用&#xff1b;环形队列常使用数组实现&#xff0c;且为了方便队列的判空、判满处理&#x…

【数据可视化】第五章—— 基于PyEcharts的数据可视化

文章目录 1. pyecharts数据可视化介绍2&#xff0e;pyecharts安装与使用3&#xff0e;全局配置项和系列配置项3.1 全局配置项3.1.1 基本元素配置项3.1.2 坐标轴配置项3.1.3 原生图形配置项 3.2 系列配置项3.2.1 样式类配置项3.2.2 标记类型配置项3.2.3 其它类配置项 4&#xff…

4。计算机组成原理(2)存储系统

嵌入式软件开发&#xff0c;非科班专业必须掌握的基本计算机知识 核心知识点&#xff1a;数据表示和运算、存储系统、指令系统、总线系统、中央处理器、输入输出系统 这一部分主要讲解了CPU的组成和扩容、CPU与存储器&#xff08;主存、辅存、缓存&#xff09;的连接 一 存储…

基于人工智能AI视频分析的智慧安监解决方案

方案背景 为了保证对园区环境风险进行有效识别&#xff0c;传统视频监控存在视频结构化利用率低的问题&#xff0c;在实际使用过程中&#xff0c;安全管理人员工作效率低下&#xff0c;依靠人工肉眼查看灵活度低&#xff0c;风险漏报概率高&#xff0c;出现异常情况跟踪不及时&…

VS2019 c++ cmake项目 打包并使用 (lib\dlll)

背景 最近项目中经常调用第三方库、带头文件、lib和dll的库&#xff0c;需要使用cmake进行项目管理&#xff0c;之前一直比较糊涂这方面&#xff0c;在这里做一个整理总结 编译汇编过程 静态链接方式&#xff1a; 把lib里面编译好的东西&#xff08;函数、变量等&#xff09…

海量请求下,高并发接口的设计思路

1. 背 景 虽然现在很多人&#xff0c;动不动就提什么高并发、请求量多大&#xff0c;数据量多少多少&#xff0c;但我可以很认真地说&#xff0c;那都是他妈的在吹牛&#xff01; 生产环境&#xff0c;真正有大请求量的&#xff0c;就那么几个业务场景&#xff0c;而且多是面…

算法记录 | Day56 动态规划

583.两个字符串的删除操作 思路&#xff1a; 1.确定dp数组&#xff08;dp table&#xff09;以及下标的含义&#xff1a;dp[i][j]&#xff1a;以i-1为结尾的字符串word1&#xff0c;和以j-1位结尾的字符串word2&#xff0c;想要达到相等&#xff0c;所需要删除元素的最少次数…

网络协议与攻击模拟-05-ICMP协议

ICMP 协议 1、理解 ICMP 协议 2、理解 ICMP 重定向 3、会使用 wireshark 分析 ICMP 重定向流量实验 一、 ICMP 基本概念 1、 ICMP 协议 Internet 控制报文协议&#xff0c;用于在 IP 主机、路由器之间传递控制消息&#xff0c;控制消息指网络通不通、主机是否可达、路由是否…

iview-admin首页的图表数据渲染问题

iview-admin的首页有几个图表&#xff0c;应该是作者自己封装的&#xff0c;有个问题是在mounted时&#xff0c;从后台获取数据&#xff0c;应该把图表根据数据重新渲染一下。 <chart-bar id"myChart" style"height: 260px;" :value"barData"…

全方位揭秘!大数据从0到1的完美落地之Shuffle和调优

MapReduce高级 shuffle阶段 概述 MapReduce会确保每个reducer的输入都是按键排序的。从map方法输出数据开始、到作为输入数据传给reduce方法的过程称为shuffle。在此&#xff0c;我们将学习shuffle是如何工作的&#xff0c;因为它有助于我们理解工作机制&#xff08;如果需要…

前端008_类别模块_新增功能

类别模块_新增功能 1、需求分析2、新增窗口实现3、列表引用新增组件4、关闭弹出窗口5、校验表单数据6、提交表单数据6.1、Mock 添加新增模拟接口6.2、Api 调用接口6.3、测试新增功能1、需求分析 点击 新增 按钮后,对话框形式弹出新增窗口输入分类信息后,点击 确定 提交表单数…

【递推专题】常见的递推“模型”总结

目录 1.斐波那契数列分析&#xff1a;代码&#xff1a; 2.平面分割问题分析&#xff1a; 3.汉诺塔问题分析&#xff1a; 4.卡特兰数分析&#xff1a; 5.第二类斯特林数总结&#xff1a; 1.斐波那契数列 分析&#xff1a; 斐波那契数列又称兔子数列&#xff0c;其原理来源于兔子…

测试知识总结

1.影响ui自动化稳定性 异常弹出对话框 --异常场景库 页面控件元素属性的细微变化--模糊匹配 延迟 --- retry 数据 -- 数据已被使用 2. 移动端应用细分为三大类&#xff1a;Web App、Native App&#xff08;原生应用&#xff09; 和 Hybrid App&#xff08;混合应用&…
最新文章