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

2023-12-01 22:28

本文主要是介绍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简介与使用方法的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/442911

相关文章

SpringBoot中使用Flux实现流式返回的方法小结

《SpringBoot中使用Flux实现流式返回的方法小结》文章介绍流式返回(StreamingResponse)在SpringBoot中通过Flux实现,优势包括提升用户体验、降低内存消耗、支持长连... 目录背景流式返回的核心概念与优势1. 提升用户体验2. 降低内存消耗3. 支持长连接与实时通信在Sp

Conda虚拟环境的复制和迁移的四种方法实现

《Conda虚拟环境的复制和迁移的四种方法实现》本文主要介绍了Conda虚拟环境的复制和迁移的四种方法实现,包括requirements.txt,environment.yml,conda-pack,... 目录在本机复制Conda虚拟环境相同操作系统之间复制环境方法一:requirements.txt方法

Nginx 重写与重定向配置方法

《Nginx重写与重定向配置方法》Nginx重写与重定向区别:重写修改路径(客户端无感知),重定向跳转新URL(客户端感知),try_files检查文件/目录存在性,return301直接返回永久重... 目录一.try_files指令二.return指令三.rewrite指令区分重写与重定向重写: 请求

MySQL 打开binlog日志的方法及注意事项

《MySQL打开binlog日志的方法及注意事项》本文给大家介绍MySQL打开binlog日志的方法及注意事项,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要... 目录一、默认状态二、如何检查 binlog 状态三、如何开启 binlog3.1 临时开启(重启后失效)

python使用库爬取m3u8文件的示例

《python使用库爬取m3u8文件的示例》本文主要介绍了python使用库爬取m3u8文件的示例,可以使用requests、m3u8、ffmpeg等库,实现获取、解析、下载视频片段并合并等步骤,具有... 目录一、准备工作二、获取m3u8文件内容三、解析m3u8文件四、下载视频片段五、合并视频片段六、错误

Python中提取文件名扩展名的多种方法实现

《Python中提取文件名扩展名的多种方法实现》在Python编程中,经常会遇到需要从文件名中提取扩展名的场景,Python提供了多种方法来实现这一功能,不同方法适用于不同的场景和需求,包括os.pa... 目录技术背景实现步骤方法一:使用os.path.splitext方法二:使用pathlib模块方法三

Python打印对象所有属性和值的方法小结

《Python打印对象所有属性和值的方法小结》在Python开发过程中,调试代码时经常需要查看对象的当前状态,也就是对象的所有属性和对应的值,然而,Python并没有像PHP的print_r那样直接提... 目录python中打印对象所有属性和值的方法实现步骤1. 使用vars()和pprint()2. 使

CSS实现元素撑满剩余空间的五种方法

《CSS实现元素撑满剩余空间的五种方法》在日常开发中,我们经常需要让某个元素占据容器的剩余空间,本文将介绍5种不同的方法来实现这个需求,并分析各种方法的优缺点,感兴趣的朋友一起看看吧... css实现元素撑满剩余空间的5种方法 在日常开发中,我们经常需要让某个元素占据容器的剩余空间。这是一个常见的布局需求

gitlab安装及邮箱配置和常用使用方式

《gitlab安装及邮箱配置和常用使用方式》:本文主要介绍gitlab安装及邮箱配置和常用使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1.安装GitLab2.配置GitLab邮件服务3.GitLab的账号注册邮箱验证及其分组4.gitlab分支和标签的

SpringBoot3应用中集成和使用Spring Retry的实践记录

《SpringBoot3应用中集成和使用SpringRetry的实践记录》SpringRetry为SpringBoot3提供重试机制,支持注解和编程式两种方式,可配置重试策略与监听器,适用于临时性故... 目录1. 简介2. 环境准备3. 使用方式3.1 注解方式 基础使用自定义重试策略失败恢复机制注意事项