GTest使用笔记

news/2024/7/3 2:30:42

1. C++测试框架

1.1. CppUnit

这是一个与JUnit类似的框架,这个框架很陈旧了,并且有着一些缺点,例如一些类可以消失,一些类名应该修改,一些宏定义应该修改,帮助很少很乱等。

1.2. CxxTest

因为CppUnit有着一系列的缺点,CppUnit的鼻祖之一重写了一套C/C++单元测试框架,这就是CxxTest。与CppUnit相比,CxxTest具有如下一些优点:

  • 不需要RTTI(运行时间类型信息);
  • 不需要成员模板功能;
  • 不需要异常处理;
  • 不需要任何外部函数库(包括内存管理、文件/控制台的输入/输出和图形库等);
  • 它完全是作为一套头文件的集合而进行发布的。

另外由于CppUnit带有Make文件, 所以只能用在主要的操作系统中,而应用到不常见操作系统中源代码及Make文件修改的工作量就会很大。CxxTest不带Make文件, 所以也可用于其他操作系统中,具有更好的可移植性和可用性。Gtest虽然也使用Makefile文件,但是通过libtool动态加载来实现,可以支持Supports Linux, Windows, Mac OS, 以及其他操作系统。

CxxTest也有一些缺点,例如需要用到perl或者Python对测试代码的头文件进行文法扫描,生成可执行代码,准备工作比较麻烦。并且CxxTest的绝大多数功能都可以使用Gtest来完成,所以一般情况下就更加推荐Gtest。

1.3. GTest

Gtest是一个跨平台(Liunx、Mac OS X、Windows、Cygwin、Windows CE and Symbian)的C++测试框架,由Google公司发布。Gtest测试框架是在不同平台上为编写C++测试而生成的。

这是Google的开源C++单元测试框架,是遵循 New BSD License (可用作商业用途)的开源项目。据说Google内部的大多数C++代码都已经使用这个测试框架进行单测,Gtest可以支持绝大多数大家所熟知的平台。

2. 安装GTest

下载源码

git clone https://github.com/google/googletest

3. 使用GTest

3.1. 代码

gtest_test.cpp文件

注意:如果有命名空间,main函数要放到命名空间外面,其实不建议使用main函数

#include "gtest/gtest.h"
#include "fun.h"TEST(fun, add) {EXPECT_EQ(1, add(2,-1));EXPECT_EQ(5, add(2,3));
}int main(int argc, char** argv) {testing::InitGoogleTest(&argc, argv);return RUN_ALL_TESTS();
}

3.2. 编译

如果test中写了main函数,则编译比较简单;如果test中没有写main函数,则编译时需要链接gtest_main

3.3. 运行

make test CTEST_OUTPUT_ON_FAILURE=TRUE GTEST_COLOR=TRUE

4. GTest的一些基本概念

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

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

5. GTest的断言

5.1. 布尔值检查

Fatal assertion

Nonfatal assertion

Verifies

ASSERT_TRUE(condition);

EXPECT_TRUE(condition);

condition is true

ASSERT_FALSE(condition);

EXPECT_FALSE(condition);

condition is false

5.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

5.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字符串有不同的内容,忽略大小写

5.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.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

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

6. 注意事项

6.1. 生成链接库时不要编UT文件

很多工程都包含UT文件,当这个工程编译链接库时,注意要把UT文件从链接库的源文件中剔除,然后单独把UT文件编成可执行文件。

6.2. 不建议使用main函数

如果链接了gtest_main,则不需要写main函数,建议使用这种方式。

参考文献

gtest简介及简单使用_网络资源是无限的-CSDN博客_gtest

gtest框架的介绍与应用_踏雪无痕-CSDN博客

GTest的安装与使用 - 晓乎 - 博客园


http://lihuaxi.xjx100.cn/news/247079.html

相关文章

mysql 加快命中_合理配置MySQL缓存 提高缓存命中率

众所周知&#xff0c;系统读取数据时&#xff0c;从内存中读取要比从硬盘上速度要快好几百倍。故现在绝大部分应用系统&#xff0c;都会最大程度的使用缓存(内存中的一个存储区域)&#xff0c;来提高系统的运行效率。MySQL数据库也不例外。在这里&#xff0c;笔者将结合自己的工…

制作OpenStack上使用的CentOS系统镜像

很多进行Openstack测试的人都发现&#xff0c;自己的openstack测试环境搭建的很成功&#xff0c;安全策略也添加了&#xff0c;但是上传镜像之后&#xff0c;却出现无法Ping通&#xff0c;无法ssh到实例等问题&#xff0c;实际上这很可能是由于我们没有使用一个正确的镜像导致的…

python argparser模块的相关使用

最近写的代码&#xff0c;需要很多文件的输入输出&#xff0c;每次更换文件都要一个个py文件进入&#xff0c;然后更换&#xff0c;非常不方便&#xff0c;由此想到了&#xff0c;采用python命令行模块解决更换的麻烦&#xff0c;通过命令行的模式&#xff0c;在一个py模块中创…

Linux下用火焰图进行性能分析

软件的性能分析, 往往需要查看 CPU 耗时, 了解瓶颈在哪里。火焰图(flame graph) 是性能分析的利器 1. 火焰图简介 很多人感冒发烧的时候, 往往会模仿神农氏尝百草的路子: 先尝尝抗病毒的药, 再试试抗细菌的药, 甭管家里有什么药挨个试, 什么中药西药, 瞎猫总会碰上死耗子, 如…

Python编程规范及性能优化

为什么80%的码农都做不了架构师&#xff1f;>>> Ptyhon编程规范 编码 所有的 Python 脚本文件都应在文件头标上 # -*- coding:utf-8 -*- 。设置编辑器&#xff0c;默认保存为 utf-8 格式。 注释 业界普遍认同 Python 的注释分为两种的概念&#xff0c;一种是由 # 开…

使用XHProf分析PHP性能瓶颈(二)

上一篇文章里&#xff0c;我们介绍了如何基于xhprof扩展来分析PHP性能&#xff0c;并记录到日志里&#xff0c;最后使用xhprof扩展自带的UI在web里展示出来。本篇文章将讲述2个知识点&#xff1a; 使用xhgui代替xhprof的默认UI界面&#xff0c;更便于分析使用tideways扩展替换x…

npm 重新安装依赖_npm-shrinkwrap锁定依赖

写在前面npm采用语义化的版本号 semver 进行控制&#xff0c;让开发过程中依赖的获取和升级变得非常容易&#xff0c;但不严格的版本号控制&#xff0c;也带来了不确定性~~npm 建议使用semver版本&#xff0c;部分包不遵循semver&#xff1b;package.json 可以使用精确的版本号…

KNN(k-NearestNeighbor)

最近工作中用到求邻近点的方法&#xff0c;于是用上了knn. KNN概述 邻近算法&#xff0c;或者说K最近邻(kNN&#xff0c;k-NearestNeighbor)分类算法是数据挖掘分类技术中最简单的方法之一。所谓K最近邻&#xff0c;就是k个最近的邻居的意思&#xff0c;说的是每个样本都可以用…