当前位置: 首页 > news >正文

Google测试框架googletest简介与使用方法

环境准备(Ubuntu)

下载
git clone https://github.com/google/googletest.git
安装
cd googletest
// 创建build目录
mkdir build
cd build
//编译安装
cmake ..
make
sudo make install
检查是否安装成功
ls /usr/local/lib// 存在以下文件则说明安装成功
libgmock.a
libgmock_main.a
libgtest.a
libgtest_main.a

重要文件

googletest
# 头文件
gtest/gtest.h# 不带 main 静态库
libgtest.a# 带 main 静态库
libgtest_main.a

当不想写 main 函数的时候,可以直接引入 libgtest_main.a;

g++ sample.cc -o sample -lgtest -lgtest_main -lpthread
g++ sample.cc -o sample -lgmock -lgmock_main -lpthread

 否则

g++ sample.cc -o sample -lgtest -lpthread
googlemock
# 头文件
gmock/gmock.h# 不带 main 静态库
libgmock.a# 带 main 静态库
libgmock_main.a

断言

断言成对出现,它们测试相同的东西,但对当前函数有不同的影响。 ASSERT_* 版本在失败时产生致命失败,并中止当前测试案例。 EXPECT_* 版本生成非致命失败,它不会中止当前函数。通常首选 EXPECT_* ,因为它们允许在测试中报告一个以上的失败。但是,如果在有问题的断言失败时继 续没有意义,则应该使用 ASSERT_* 。
所有断言宏都支持输出流,也就是当出现错误的时候,我们可以通过流输出更详细的信息;注意编 码问题,经流输出的信息会自动转换为 UTF-8

EXPECT_TRUE(my_condition) << "My condition is not true";

明确指定成功或者失败

有时候我们测试案例当中的条件太复杂,不能使用断言,那么自己写判断语句;自己返回 成功或 者失败;
 SUCCEED() 或者 FAIL()

布尔条件

EXPECT_TRUE( condition )
ASSERT_TRUE( condition )
EXPECT_FALSE( condition )
ASSERT_FALSE( condition )

二元比较 

val1 = val2 :

EXPECT_EQ( val1 , val2 )

ASSERT_EQ( val1 , val2 )

val1 != val2 :

EXPECT_NE( val1 , val2 )

ASSERT_NE( val1 , val2 )

注意:比较空指针的时候;

使用 EXPECT_NE( ptr , nullptr) 而不是 EXPECT_NE( ptr , NULL) 。

val1 < val2 :

EXPECT_LT( val1 , val2 )

ASSERT_LT( val1 , val2 )

val1 <= val2 :

EXPECT_LE( val1 , val2 )

ASSERT_LE( val1 , val2 )

val1 > val2 :

EXPECT_GT( val1 , val2 )

ASSERT_GT( val1 , val2 )

val1 >= val2 :

EXPECT_GE( val1 , val2 )

ASSERT_GE( val1 , val2 )

谓词断言

谓词断言能比 EXPECT_TRUE 提供更详细的错误消息; 

EXPECT_PRED1( pred , val1 ) \

EXPECT_PRED2( pred , val1 , val2 ) \

EXPECT_PRED3( pred , val1 , val2 , val3 ) \

EXPECT_PRED4( pred , val1 , val2 , val3 , val4 ) \

EXPECT_PRED5( pred , val1 , val2 , val3 , val4 , val5 )

ASSERT_PRED1( pred , val1 ) \

ASSERT_PRED2( pred , val1 , val2 ) \

ASSERT_PRED3( pred , val1 , val2 , val3 ) \

ASSERT_PRED4( pred , val1 , val2 , val3 , val4 ) \

ASSERT_PRED5( pred , val1 , val2 , val3 , val4 , val5 )

// Returns true if m and n have no common divisors except 1.
bool MutuallyPrime(int m, int n) { ... }
...
const int a = 3;
const int b = 4;
const int c = 10;
...
EXPECT_PRED2(MutuallyPrime, a, b); // Succeeds
EXPECT_PRED2(MutuallyPrime, b, c); // Fails

 得到的错误信息:

MutuallyPrime(b, c) is false, where
b is 4
c is 10

googletest

函数测试以及类测试
#define TEST(test_suite_name,test_name)
test fixture(测试夹具)

用相同的数据配置来测试多个测试案例。

// 定义类型,继承自 testing::Test
class TestFixtureSmpl : public testing::Test {
protected:
void SetUp() {} // 测试夹具测试前调用的函数 -- 做初始化的工作
void TearDown() {} // 测试夹具测试后调用的函数 -- 做清理的工作
};
// 需要在 TEST_F 中书写测试用例
#define TEST_F(test_fixture,test_name)
// 如果需要复用测试夹具,只需要继承自 TestFixtureSmpl
class TestFixtureSmpl_v2 : public TestFixtureSmpl {
};
类型参数化
基础

有时候相同的接口,有多个实现,下面是复用测试代码流程; 复用测试案例

using testing::Test;
using testing::Types;
// 先申明测试夹具
template <class T>
class TestFixtureSmpl : public testing::Test {
protected:
void SetUp() {} // 测试夹具测试前调用的函数 -- 做初始化的工作
void TearDown() {} // 测试夹具测试后调用的函数 -- 做清理的工作
};
// 枚举测试类型
typedef Types<Class1, Class2, class3, ...> Implementations;
// #define TYPED_TEST_SUITE(CaseName,Types,__VA_ARGS__...)
// 注意 casename 一定要与测试夹具的名字一致
TYPED_TEST_SUITE(TestFixtureSmpl, Implementations);
// #define TYPED_TEST(CaseName,TestName)
// 开始测试, CaseName 要与 TYPED_TEST_SUITE 一致
TYPED_TEST(TestFixtureSmpl, TestName)
进阶

有时候你写了某个接口,期望其他人实现它,你可能想写一系列测试,确保其他人的实现满足你的 测试;

// 首先声明测试类型参数化(_P 是 parameterized or pattern)
// #define TYPED_TEST_SUITE_P(SuiteName)
TYPED_TEST_SUITE_P(TestFixtureSmpl);
// 书写测试, suiteName 与上面一致
// #define TYPED_TEST_P(SuiteName,TestName)
TYPED_TEST_P(TestFixtureSmpl,TestName)
// 枚举所有测试
// #define REGISTER_TYPED_TEST_SUITE_P(SuiteName,__VA_ARGS__...)
REGISTER_TYPED_TEST_SUITE_P(TestFixtureSmpl,
TestName1,TestName2,...)
// 上面定义的是抽象测试类型
// 其他人实现功能后,开始测试,假如实现了 OnTheFlyPrimeTable 和
PreCalculatedPrimeTable
typedef Types<OnTheFlyPrimeTable, PreCalculatedPrimeTable>
PrimeTableImplementations;
// #define
INSTANTIATE_TYPED_TEST_SUITE_P(Prefix,SuiteName,Types,__VA_ARGS__...)
INSTANTIATE_TYPED_TEST_SUITE_P(
instance_name,
testcase,
typelist...)
事件

可以通过 googletest 的事件机制,在测试前后进行埋点处理;

模板模式

// The interface for tracing execution of tests. The methods are organized
in
// the order the corresponding events are fired.
class TestEventListener {
public:
virtual ~TestEventListener() {}
// Fired before any test activity starts.
virtual void OnTestProgramStart(const UnitTest& unit_test) = 0;
// Fired before each iteration of tests starts. There may be more than
// one iteration if GTEST_FLAG(repeat) is set. iteration is the iteration
// index, starting from 0.
virtual void OnTestIterationStart(const UnitTest& unit_test,
int iteration) = 0;
// Fired before environment set-up for each iteration of tests starts.
virtual void OnEnvironmentsSetUpStart(const UnitTest& unit_test) = 0;
// Fired after environment set-up for each iteration of tests ends.
virtual void OnEnvironmentsSetUpEnd(const UnitTest& unit_test) = 0;
// Fired before the test suite starts.
virtual void OnTestSuiteStart(const TestSuite& /*test_suite*/) {}
// Legacy API is deprecated but still available
#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
virtual void OnTestCaseStart(const TestCase& /*test_case*/) {}
#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
// Fired before the test starts.
virtual void OnTestStart(const TestInfo& test_info) = 0;
// Fired after a failed assertion or a SUCCEED() invocation.
// If you want to throw an exception from this function to skip to the
next
// TEST, it must be AssertionException defined above, or inherited from
it.
virtual void OnTestPartResult(const TestPartResult& test_part_result) = 0;
// Fired after the test ends.
virtual void OnTestEnd(const TestInfo& test_info) = 0;
// Fired after the test suite ends.
virtual void OnTestSuiteEnd(const TestSuite& /*test_suite*/) {}
// Legacy API is deprecated but still available
#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
virtual void OnTestCaseEnd(const TestCase& /*test_case*/) {}
#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
// Fired before environment tear-down for each iteration of tests starts.
virtual void OnEnvironmentsTearDownStart(const UnitTest& unit_test) = 0;
// Fired after environment tear-down for each iteration of tests ends.
virtual void OnEnvironmentsTearDownEnd(const UnitTest& unit_test) = 0;
// Fired after each iteration of tests finishes.
virtual void OnTestIterationEnd(const UnitTest& unit_test,
int iteration) = 0;
// Fired after all test activities have ended.
virtual void OnTestProgramEnd(const UnitTest& unit_test) = 0;
};

相关文章:

Google测试框架googletest简介与使用方法

环境准备&#xff08;Ubuntu&#xff09; 下载 git clone https://github.com/google/googletest.git 安装 cd googletest // 创建build目录 mkdir build cd build //编译安装 cmake .. make sudo make install 检查是否安装成功 ls /usr/local/lib// 存在以下文件则说明…...

进程的创建:fork()

引入 创建进程的方式我们已经学习了一个&#xff01;在我们运行指令(或者运行我们自己写的可执行程序)的时候不就是创建了一个进程嘛&#xff1f;那个创建进程的方式称为指令级别的创建子进程&#xff01; 那如果我们想要在代码中创建进程该怎么办呢&#xff1f; fork() for…...

Fabric:创建应用通道

搭建自定义网络可以参考文章&#xff1a; https://blog.csdn.net/yeshang_lady/article/details/134113296 1 创建通道 网络搭建完成之后&#xff0c;就可以开始创建通道了。Fabric V2.5.4中可以在不创建系统通道的情况下直接创建应用通道。 1.1 修改配置文件 先创建配置文…...

力扣每日一题(2023-11-30)

力扣每日一题 题目&#xff1a;1657. 确定两个字符串是否接近 日期&#xff1a;2023-11-30 用时&#xff1a;21 m 07 s 时间&#xff1a;11ms 内存&#xff1a;43.70MB 代码&#xff1a; class Solution {public boolean closeStrings(String word1, String word2) {if(word1.…...

内部类Lambda

静态内部类 /*** 静态成员是在类加载成字节码时就已经存在的,静态只能访问静态*/ public class Demo {public static void main(String[] args) {Outer.Inner.show();} }class Outer {int num1 10;static int num2 20;static class Inner {static void show() {Outer outer …...

设一棵二叉树中各结点的值互不相同,其先序遍历序列和中序遍历序列分别存于两个一维数组A[1...n]和 Bfl...n]中,试编写算法建立该二叉树的二叉链表。

题目描述&#xff1a;设一棵二叉树中各结点的值互不相同&#xff0c;其先序遍历序列和中序遍历序列分别存于两个一维数组A[1…n]和 B[1…n]中&#xff0c;试编写算法建立该二叉树的二叉链表。 分析&#xff1a; 对于一颗二叉树&#xff0c;知道其中序和先序序列就可以完全确定…...

什么是Daily Scrum?

Daily Scrum&#xff08;每日站会&#xff09;&#xff0c;Scrum Master要确保这个会在每天都会开。这个会的目的就是检查正在做的东西和方式是否有利于完成Sprint目的&#xff0c;并及时做出必要的调整。 每日站会一般只开15分钟&#xff0c;为了让事情更简单些&#xff0c;这…...

逆波兰表达式求值[中等]

优质博文&#xff1a;IT-BLOG-CN 一、题目 给你一个字符串数组tokens&#xff0c;表示一个根据 逆波兰表示法 表示的算术表达式。请你计算该表达式。返回一个表示表达式值的整数。 有效的算符为 ‘’、‘-’、‘*’ 和 ‘/’ 。 每个操作数&#xff08;运算对象&#xff09;都…...

Oracle连接和使用

5. Oracle连接和使用 5.1. sqlplus sqlplus作为甲骨文公司提供的一款本族工具产品,有着悠久的历史和积淀,它几乎伴随着Oracle数据库产生至今的整个生命周期,而且,还会继续和Oracle数据库产品相伴一直发展下去。该工具看似简单灵活的背后,却为广大用户使用Oracle数据库提…...

redis单线程为什么这么快

redis单线程为什么这么快 redis是使用的单线程来进行操作的&#xff0c;因为所有的数据都是在内存中的&#xff0c;内存操作特别快。而且单线程避免了多线程切换性能损耗问题 单线程如何处理并发客户端连接&#xff1f; redis利用epoll来实现IO多路复用&#xff0c;将连接信息和…...

工业机器视觉megauging(向光有光)使用说明书(五,轻量级的visionpro)

这个说明主要介绍抓线功能。 第一步&#xff0c;添加线工具&#xff0c;鼠标双击工具箱“抓线”&#xff0c;出现如下界面&#xff1a; 第二步&#xff0c;我们拉一条&#xff0c;“九点标定”到“抓线1”的线&#xff0c;和visionpro操作一样&#xff1a; 第三步&#xff0c;…...

【LittleXi】2023年广东工业大学腾讯杯新生程序设计竞赛

文章目录 【LittleXi】2023年广东工业大学腾讯杯新生程序设计竞赛A.星期几考试&#xff1f;C.信件D、乘除法E、不知道叫什么名字F.我要学会盾反&#xff01;G.闪闪发光心动不已&#xff01;H.不想想背景的gcdI.uu爱玩飞行棋J.火柴人小游戏K .有趣的BOSS 【LittleXi】2023年广东…...

【C语言:数据在内存中的存储】

文章目录 1.整数在内存中的存储1.1整数在内存中的存储1.2整型提升 2.大小端字节序2.1什么是大小端2.2为什么有大小端之分 3.整数在内存中的存储相关题目题目一题目二题目三题目四题目五题目六题目七 4.浮点数在内存中的存储4.1浮点数存的过程4.2浮点数取得过程 在这之前呢&…...

每日一练:阿姆斯特朗数

如果一个 n 位正整数等于其各位数字的 n 次方之和&#xff0c;则称该数为阿姆斯特朗数。 例如 1^3 5^3 3^3 153。 1000 以内的阿姆斯特朗数&#xff1a; 1, 2, 3, 4, 5, 6, 7, 8, 9, 153, 370, 371, 407。...

fatal: remote error: upload-pack: not our ref (未解决问题)

PX4使用 git submodule update --init --recursive报错 fatal: remote error: upload-pack: not our ref解决办法参考&#xff1a;https://stackoverflow.com/questions/61163082/why-does-git-submodule-update-fail-with-fatal-remote-error-upload-pack-not-o 感觉就是清…...

Python 3 使用 read()、readline()、readlines() 函数 读取文件

1 样例文件 example.txt 春晓 孟浩然〔唐代〕 春眠不觉晓&#xff0c;处处闻啼鸟。 夜来风雨声&#xff0c;花落知多少。 2 分别使用 read()、readline()、readlines() 函数 2.1 # read() -------- 一次性读取所有文本&#xff0c;以字符串的形式返回结果。 # read() ----…...

勒索解密后oracle无法启动故障处理----惜分飞

客户linux平台被勒索病毒加密,其中有oracle数据库.客户联系黑客进行解密【勒索解密oracle失败】,但是数据库无法正常启动,dbv检查数据库文件报错 [oraclehisdb ~]$ dbv filesystem01.dbf DBVERIFY: Release 11.2.0.1.0 - Production on 星期一 11月 27 21:49:17 2023 Copyrig…...

Leetcode144. 二叉树的前序遍历-C语言

文章目录 题目介绍题目分析解题思路1.创建一个数组来储存二叉树节点的值2.根据二叉树的大小来开辟数组的大小3.边前序遍历边向创建的数组中存入二叉树节点的值 完整代码 题目介绍 题目分析 题目要求我们输出二叉树按前序遍历排列的每个节点的值。 解题思路 1.创建一个数组来…...

dmesg命令在软件测试中的实际应用

简介&#xff1a;当你想要了解 Linux 系统在启动时究竟发生了什么&#xff1f;或者当硬件设备不工作时&#xff0c;如何进行调试&#xff1f;这就是 dmesg 命令的用武之地。本文将介绍 dmesg 的基本功能&#xff0c;并深入探讨其在软件测试中的实际应用。 历史攻略&#xff1a…...

【渗透】记录阿里云CentOS一次ddos攻击

文章目录 发现防御 发现 防御 流量清洗 使用高防...

前端面试提问(3)

1、js两个数相加会不会丢精度&#xff1f; 可能会遇到精度丢失的问题。JavaScript 使用的是 IEEE 754 浮点数标准&#xff0c;即一种二进制表示法&#xff0c;有时不能准确地表示十进制小数。如果你需要进行精确的十进制数值计算&#xff0c;可以使用一些处理精确数值的库&…...

fl studio21.2最新汉化中文完整版网盘下载

fl studio 21中文版是Image-Line公司继20版本之后更新的水果音乐制作软件&#xff0c;很多用户不太理解&#xff0c;为什么新版本不叫fl studio 21或fl studio2024&#xff0c;非得直接跳到21.2版本&#xff0c;其实该版本是为了纪念该公司22周年&#xff0c;所以该版本也是推出…...

差分数组相关知识点以及刷题

差分数组 差分数组是什么&#xff1f; **举例&#xff1a;**对于数组考虑数组 a[1,3,3,5,8]&#xff0c;对其中的相邻元素两两作差&#xff08;右边减左边&#xff09;&#xff0c;得到数组 [2,0,2,3]。然后在开头补上 a[0]&#xff0c;得到差分数组&#xff1a; ​ d[1,2,0…...

使用 DMA 在 FPGA 中的 HDL 和嵌入式 C 之间传输数据

使用 DMA 在 FPGA 中的 HDL 和嵌入式 C 之间传输数据 该项目介绍了如何在 PL 中的 HDL 与 FPGA 中的处理器上运行的嵌入式 C 之间传输数据的基本结构。 介绍 鉴于机器学习和人工智能等应用的 FPGA 设计中硬件加速的兴起&#xff0c;现在是剥开几层“云雾”并讨论 HDL 之间来回传…...

uniapp地图基本使用及解决添加markers不生效问题?

uniapp地图使用 App端 通过 nvue 页面实现地图 文章目录 uniapp地图使用效果图templatejs添加 marker使用地图查看位置移到到当前位置 效果图 template <template><view class"mapWrap"><!-- #ifdef APP-NVUE --><map class"map-containe…...

使用系统ProgressBar实现三色进度条

使用系统ProgressBar实现如图三色进度条&#xff1a; //布局中<ProgressBarandroid:layout_width"0dp"android:layout_height"8dp"android:layout_marginLeft"16dp"app:layout_constraintBottom_toBottomOf"id/photo"app:layout_c…...

Vue3中的组合式API的详细教程和介绍

文章目录 前言介绍组合式 API 基础setup 组件选项 带 ref 的响应式变量生命周期钩子注册内部 setupwatch 响应式更改独立的 computed 属性后言 前言 hello world欢迎来到前端的新世界 &#x1f61c;当前文章系列专栏&#xff1a;vue.js &#x1f431;‍&#x1f453;博主在前端…...

Java后端开发——JDBC(万字详解)

Java后端开发——JDBC&#xff08;万字详解&#xff09; 今日目标 掌握JDBC的的CRUD理解JDBC中各个对象的作用掌握Druid的使用 1&#xff0c;JDBC概述 在开发中我们使用的是java语言&#xff0c;那么势必要通过java语言操作数据库中的数据。这就是接下来要学习的JDBC。 1.1 …...

python etree.HTML 以及xpath 解析网页的工具

文章目录 导入模块相关语法实战 导入模块 from lxml import etree相关语法 XPath&#xff08;XML Path Language&#xff09;是一种用于在XML文档中定位和选择元素的语言。XPath的主要应用领域是在XML文档中进行导航和查询&#xff0c;通常用于在XML中选择节点或节点集合。以…...

电机伺服驱动学习笔记(7)待编辑

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、pandas是什么&#xff1f;二、使用步骤1.引入库2.读入数据 总结 前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; 例如&#xff1a;…...