用gtest测试类的私有成员
gtest使用手册

gtest 使用手册gtest 是一个流行的 C++单元测试框架,它提供了丰富的功能和简洁的 API,使得编写和运行单元测试变得更加容易和高效。
本文将介绍 gtest 的基本概念和使用方法,帮助读者快速上手并熟练使用 gtest 进行单元测试。
下面是本店铺为大家精心编写的3篇《gtest 使用手册》,供大家借鉴与参考,希望对大家有所帮助。
《gtest 使用手册》篇1一、什么是 gtest?gtest 是一个由 Google 开发的 C++单元测试框架,旨在为开发者提供一种简单、高效的方式来编写和运行单元测试。
gtest 提供了丰富的功能和简洁的 API,可以与各种编译器和 IDE 集成,并支持多种测试类型和断言风格。
二、gtest 的基本概念1. 测试套件(Test Suite):测试套件是 gtest 的基本单位,它包含一个或多个测试用例(Test Case)。
每个测试套件都有一个入口函数,该函数负责初始化和清理测试环境。
2. 测试用例(Test Case):测试用例是测试套件中的基本测试单元,它包含一个或多个测试步骤,每个测试步骤都包含一个预期结果和一个实际结果。
3. 断言(Assertion):断言是 gtest 中用于验证测试结果的一种机制,它用于比较预期结果和实际结果是否相等。
gtest 提供了多种断言类型,包括 EXPECT_EQ、EXPECT_NE、EXPECT_TRUE、EXPECT_FALSE 等。
4. 测试助手(Test Helper):测试助手是一种特殊的测试用例,它用于为其他测试用例提供共性的测试步骤和断言。
三、gtest 的使用方法1. 安装 gtest:在使用 gtest 之前,需要先安装 gtest。
可以使用 CMake 或 Maven 等构建工具来安装 gtest。
2. 编写测试用例:编写测试用例时,需要继承testing::TestWithParam 类,并实现 TestBody 函数。
unittest mock private方法

主题:unittest中如何mock私有方法在使用Python进行软件开发时,我们经常会用到unittest模块来进行单元测试。
在进行单元测试时,有时我们需要测试一个类的某个方法,但是这个方法调用了类中的私有方法,这时就需要对这个私有方法进行mock处理,以便顺利进行单元测试。
本文将介绍如何在unittest中mock私有方法,帮助读者更好地进行单元测试。
一、为什么需要mock私有方法在进行单元测试时,我们通常是针对一个方法进行测试的,但有时这个方法内部会调用类中的私有方法,私有方法也可能会调用其他模块中的方法。
如果我们不对私有方法进行mock处理,单元测试时就会被私有方法所影响,导致测试结果不准确。
我们需要mock私有方法以隔离被测试方法的影响,确保单元测试能够独立进行并得到准确的结果。
二、如何mock私有方法在unittest中,我们可以借助unittest.mock模块来mock私有方法。
我们需要导入unittest和unittest.mock模块,然后使用patch装饰器来对私有方法进行mock处理。
```pythonimport unittestfrom unittest.mock import patchclass MyClass:def __init__(self):passdef _private_method(self):passdef public_method(self):self._private_method()```以上是一个简单的类,其中包含一个私有方法_private_method和一个公有方法public_method。
接下来,我们将介绍如何使用unittest.mock来mock私有方法。
1. 使用patch装饰器patch装饰器可以帮助我们临时替换一个对象的属性,这里我们可以借助patch来mock私有方法。
下面是一个示例:```pythonclass TestMyClass(unittest.TestCase):patch('MyClass._private_method')def test_public_method(self, mock_private_method):my_obj = MyClass()my_obj.public_method()mock_private_method.assert_called_once()```在上面的示例中,我们使用patch装饰器来mock私有方法_private_method,将其替换为mock_private_method。
gtest类方法

gtest类方法gtest是Google Test的简称,它是一个C++的单元测试框架。
它由google公司开发,用于测试C++应用程序的正确性。
gtest提供了一个全面的测试框架,包括断言、测试套件和测试用例,可以很容易地写出可维护和易读的测试代码。
1.TEST宏:TEST宏用于定义一个测试用例,它接受两个参数,第一个参数是测试用例名称,第二个参数是测试用例中的测试点名称。
在测试用例中,可以使用gtest提供的各种断言函数来验证代码逻辑的正确性。
例如:TEST(MyTestCase, MyTestPoint)//测试点代码ASSERT_EQ(2+2,4);2.TEST_F宏:TEST_F宏与TEST宏类似,不同之处在于它可以使用测试夹具(Fixture)。
测试夹具是为了简化测试代码而引入的概念,它可以在测试用例执行前进行一些初始化操作,在测试用例执行后进行一些清理操作。
测试夹具可以帮助我们在不同的测试用例中复用一些代码逻辑。
例如:class MyTestFixture : public ::testing::Testprotected://测试用例执行前的初始化操作void SetUp( override//初始化操作}//测试用例执行后的清理操作void TearDown( override//清理操作}};TEST_F(MyTestFixture, MyTestPoint)//测试点代码ASSERT_EQ(2+2,4);3.TEST_P宏:TEST_P宏用于定义一个测试用例生成器,它可以根据参数化生成多个测试用例。
测试用例生成器接受两个参数,第一个参数是测试用例的参数化名称,第二个参数是测试用例中的参数名称。
测试用例生成器需要结合INSTANTIATE_TEST_CASE_P宏来使用。
例如:class MyTestFixture : public ::testing::TestWithParam<int> };TEST_P(MyTestFixture, MyTestPoint)int value = GetParam(;//测试点代码ASSERT_EQ(value + value, value * 2);INSTANTIATE_TEST_CASE_P(MyTestValues,MyTestFixture, ::testing::Values(1, 2, 3));4.TEST_SUITE宏:TEST_SUITE宏用于定义一个测试套件,它接受一个参数,用于定义测试套件的名称。
GoogleTest(GTest)使用方法和源码解析

GoogleTest(GTest)使用方法和源码解析在分析源码之前,我们先看一个例子。
以《Google Test(GTest)使用方法和源码解析——概况》一文中最后一个实例代码为基准,修改最后一个“局部测试”结果为错误。
(转载请指明出于breaksoftware的csdn博客)[cpp] view plain copyprint?1.class ListTest : public testing::Test {2.protected:3.virtual void SetUp() {4._m_list[0] = 11;5._m_list[1] = 12;6._m_list[2] = 13;7.}8.int _m_list[3];9.};10.TEST_F(ListTest, FirstElement) {11.EXPECT_EQ(11, _m_list[0]);12.}13.14.TEST_F(ListTest, SecondElement) {15.EXPECT_EQ(12, _m_list[1]);16.}17.18.TEST_F(ListTest, ThirdElement) {19.EXPECT_EQ(0, _m_list[2]);20.}然后我们观察其输出,从下面的结果我们可以分析出GTest帮我们统计了:•有多少测试用例•一个测试用例中有多少测试特例•一个测试用例中有多少测试特例成功•一个测试用例中有多少测试特例失败•失败的原因、位置、期待结果、实际结果[plain] view plain copyprint?1.Running main() from gtest_2.[==========] Running 3 tests from 1 test case.3.[----------] Global test environment set-up.4.[----------] 3 tests from ListTest5.[ RUN ] ListTest.FirstElement6.[ OK ] ListTest.FirstElement (0 ms)7.[ RUN ] ListTest.SecondElement8.[ OK ] ListTest.SecondElement (0 ms)9.[ RUN ] ListTest.ThirdElement10.../samples/sample11_:86: Failure11.Expected: 012.To be equal to: _m_list[2]13.Which is: 1314.[ FAILED ] ListT est.ThirdElement (0 ms)15.[----------] 3 tests from ListTest (0 ms total)16.17.[----------] Global test environment tear-down18.[==========] 3 tests from 1 test case ran. (0 ms tot al)19.[ PASSED ] 2 tests.20.[ FAILED ] 1 test, listed below:21.[ FAILED ] ListT est.ThirdElement22.23. 1 FAILED TEST在《Google Test(GTest)使用方法和源码解析——自动调度机制分析》一文中,我们分析了,测试用例对象指针将保存在类UnitTestImpl中[cpp] view plain copyprint?1.// The vector of TestCases in their original order. It owns the2.// elements in the vector.3.std::vector<TestCase*> test_cases_;那么结果的统计,肯定也是针对这个vector变量的。
gtest使用教程

运行截屏
参数化测试
• 参数化测试在有些时候可以简化测试代码的编写,减少其 冗余。不过这个技术较少使用。下面是其一个例子:
class IsPrimeParamTest : public::testing::TestWithParam<int>{}; TEST_P(IsPrimeParamTest, HandleTrueReturn) { int n = GetParam(); EXPECT_TRUE(IsPrime(n)); } // 定义参数 INSTANTIATE_TEST_CASE_P(TrueReturn, IsPrimeParamTest, testing::Values(3, 5, 11, 23, 17));
后两种事件较为常用,下面一个例子演示其效果。
事件机制实例
class FooTest : public testing::Test { public: static void SetUpTestCase(){ cout << "SetUpTestCase" << endl;} static void TearDownTestCase(){ cout << "TearDownTestCase" << endl;} virtual void SetUp(){ cout << "SetUp" << endl;} virtual void TearDown(){ cout << "TearDown" << endl;} }; TEST_F(FooTest, Test0){ cout << "Test0" << endl;} TEST_F(FooTest, Test1){ cout << "Test1" << endl;}
Google单元测试框架gtest之官方sample笔记1--简单用例

Google单元测试框架gtest之官⽅sample笔记1--简单⽤例1.0 通⽤部分和常见的测试⼯具⼀样,gtest提供了单体测试常见的⼯具和组件。
⽐如判断各种类型的值相等,⼤于,⼩于等,管理多个测试的测试组如testsuit下辖testcase,为了⽅便处理初始化数据减少重复代码,提供了setup和teardown函数。
官⽅⽂档称:TEST has two parameters: the test case name and the test name. 第⼀个是case名称,第⼆个是test名称,这是google的名词称呼⽅法,其实就是⼀般意义上的testsuit和testcase,前者是组,后者是测试⽤例,为了⽅便测试管理,把⼏个相关的测试放到⼀起统称为⼀个测试组。
这是⼀个编程约定,但如果把不相⼲的测试放到⼀个test_case_name下,也不会报错,只是做测试总结和汇总的时候不⽅便⽽已。
# define TEST(test_case_name, test_name) GTEST_TEST(test_case_name, test_name)关于TEST宏,这是⼀个⼀层包⼀层的宏定义,虽然google编程规范说不建议⽤宏,但是gtest却⼤量的使⽤宏来创建类和函数,使⽤宏可以给⽤户更加简洁的接⼝,在效率上也有优势,但是读起来很晦涩。
⼀般的,在基础⼯具和底层API中,宏还是由⼴⼤的应⽤空间,因为这⼀部分基本上不怎么变化,那些写底层⼯具的⼤⽜们有能⼒驾驭这种反常规的写法。
使⽤宏来实现底层的重复性⼯作或者封装复杂的接⼝,在开源项⽬中是很常见的⽅式。
Sample #1 shows the basic steps of using googletest to test C++ functions.Sample #2 shows a more complex unit test for a class with multiple member functions.Sample #3 uses a test fixture.Sample #4 teaches you how to use googletest and googletest.h together to get the best of both libraries.Sample #5 puts shared testing logic in a base test fixture, and reuses it in derived fixtures.Sample #6 demonstrates type-parameterized tests.Sample #7 teaches the basics of value-parameterized tests.Sample #8 shows using Combine() in value-parameterized tests.Sample #9 shows use of the listener API to modify Google Test's console output and the use of its reflection API to inspect test results.Sample #10 shows use of the listener API to implement a primitive memory leak checker.1.1 sample1官⽅sample1有2个函数,阶乘函数int Factorial()和判断素数函数bool IsPrime(int n)。
gtest单元测试方法

gtest单元测试方法gtest单元测试方法1. 什么是gtest单元测试方法gtest单元测试方法是指使用Google Test(简称gtest)框架进行软件单元测试的一种方法。
gtest是一个开源的C++单元测试框架,它提供了丰富的断言和测试工具,可以帮助开发者编写可靠的、易于维护的单元测试。
2. 使用gtest编写单元测试方法的步骤下面是使用gtest编写单元测试方法的步骤:1.安装gtest框架:首先需要将gtest框架下载到本地,并进行安装和配置。
2.编写测试用例:根据需要,编写需要测试的代码和相应的测试用例,在测试用例中调用待测试代码,并使用gtest的断言进行验证。
3.构建和运行测试:通过编译器构建测试代码,并执行生成的可执行文件,查看测试结果。
4.分析结果:根据测试结果,进行相应的修改和优化。
3. 测试用例的编写测试用例是指对待测试代码的某个功能进行测试的一组测试方法。
在gtest中,测试用例是由宏定义的方式进行定义的,下面是一个测试用例的示例:TEST(TestCaseName, TestName) {// 在这里编写测试代码// 调用待测试代码并使用断言进行验证EXPECT_EQ(4, add(2, 2));}•TEST是一个宏定义,用于定义一个测试用例。
TestCaseName 是测试用例的名称,TestName是具体的测试方法的名称。
•在测试用例中,可以编写测试代码,并调用待测试的代码。
使用EXPECT_*系列的断言检查测试结果,如EXPECT_EQ用于判断两个值是否相等。
4. 编译和运行测试使用gtest编写的测试代码,需要通过编译器进行构建,并执行生成的可执行文件进行测试。
下面是使用命令行进行编译和运行的示例:1.编译测试代码:使用编译器将测试代码编译为可执行文件。
$ g++ -o test -lgtest -lgtest_main2.运行测试:执行生成的可执行文件进行测试。
c++ gtest例子

c++ gtest例子Google Test(简称GTest)是Google为C++编写的一个开源的单元测试框架。
它为C++开发者提供了一套简单易用的API,用来编写、组织和运行单元测试。
以下是一个使用GTest的基本示例,展示了如何设置和运行测试用例。
```cpp#include <gtest/gtest.h>// 被测试的函数int add(int a, int b) {return a + b;}// 测试用例1:测试加法运算TEST(AddTest, PositiveNumbers) {EXPECT_EQ(3, add(1, 2));EXPECT_EQ(5, add(2, 3));}// 测试用例2:测试加法运算的边界条件TEST(AddTest, ZeroAndNegativeNumbers) {EXPECT_EQ(1, add(0, 1));EXPECT_EQ(-1, add(1, -2));}int main(int argc, char* argv[]) {// 初始化GTest框架::testing::InitGoogleTest(&argc, argv);// 运行所有测试用例return RUN_ALL_TESTS();}```上述代码中,定义了一个名为add的函数,接收两个整数参数,返回它们的和。
然后,我们使用GTest的宏定义TEST来定义两个测试用例。
第一个测试用例AddTest.PositiveNumbers测试了两个正数相加的结果,使用GTest的EXPECT_EQ宏来验证预期结果。
第二个测试用例AddTest.ZeroAndNegativeNumbers测试了零和负数相加的结果。
通过这样定义多个测试用例,我们可以对被测函数的不同输入和边界条件进行全面的测试。
在main函数中,我们首先使用::testing::InitGoogleTest来初始化GTest框架,然后使用RUN_ALL_TESTS运行所有的测试用例。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
用gtest测试类的私有成员
使用gtest、或者cppunit之类的框架编写单元测试代码,一个最常见的问题是对类私有成员的测试与验证。
理想情况下,我们希望在测试中,类中所有的数据与方法都是可以访问的;而在产品代码中,只暴露实现定义好的接口。
gtest官方文档中,也提到了对私有成员的处理,方法不外乎两种:一是使用friend关键字,骗取信任得以通行;二是重构采用Pimpl模式,公共类中只暴露接口,而实现类中暴露所有细节(public),测试时包含实现类即可。
但这两个方法都试了一下,觉不太方便。
∙使用friend关键字
gtest提供了一个FRIEND_TEST的宏,用来将一个test声明为产品类的
友元。
其缺点是显而易见的。
一是需要往产品类中添加纯测试代码;二是每加一个test,需要在产品类中添加一项FRIEND_TEST。
∙重构采用Pimpl模式
我认可Pimpl模式,但同时我也不会对所有的类都这么做。
所以如果让我只是为了支持测试而做这样的重构,我可能并不情愿。
况且,手工重构很麻烦,而我手头也没有这么个自动化的工具。
(当然,我相信这是可以自动化的)
其实我们想要达到的目的无非是:在产品代码中,该pubic的是public,该private的还是private;而在测试代码中,全部都是public。
于是:
1 #ifdef GTEST
2 #define private public
3 #define protected public
4 #endif
将其放在每个类的声明前,或者放在一个单独的头文件如ForcePublic.h中并包含之。
这样,在编译测试代码时,加上GTEST的预编译宏,就可以非常方便的使用被测试类中的任何成员了,并不会对产品代码产生任何的影响。
如果你是以纯源代码的方式使用你的产品类的,这个方法没有任何问题;但如果你是通过静态库,或者动态库的方式使用你的产品类的,在测试代码中若直接使用这些库,编译是没有问题,因为全伪装成了public,但在链接的时候,因为private的成员是没有从库中导出来的,必然会出现链接错误。
此时有两个方案:一是以GTEST的方式重新编译库;二是直接将产品源代码编译进你的测试工程中去。
我使用的是动态库,选择了将代码编译进测试工程的方法,为了解决dllexport, dllimport相关的一些编译问题,还做了如下定义:
1 #ifdef TXNMGR_EXPORTS
2 #define TXNMGR_API __declspec(dllexport)
3 #else
4 #ifdef GTEST
5 #define TXNMGR_API
6 #else
7 #define TXNMGR_API __declspec(dllimport)
8 #endif
9 #endif
这样,在测试工程中,TXNMGR_API宏的定义为空,自然被忽略了,而不会影响
到产品代码。
感觉着这种方法的好处在于只要在一开始做一些小小的修改,便可以一劳永逸的解决访问所有产品类所有私有成员的问题;由于我们改变的只是成员的访问级别,对类的行为应该没有什么影响。
更新:
在gtest的google group中就这个问题提出了讨论,大家指出这种方式的问题在于:
∙使得访问私有成员过分容易,从而导致写出来的test访问私有成员的可能性增大。
测试访问了私有成员,也就是依赖于实现,这让单元测试成为
你重构的负担,而不是保证。
∙万战勇同学也指出,这种方法是不标准的C++用法: 一是C++标准不允许重定义关键词,所以这种方法即使此时在你当前的编译器上是可行的,你
也不能保证将来,或者在其他编译器上可行;二是public, protected
private等访问修饰符可能会影响对象成员的布局,这样当你的测试是直
接链接到产品代码时会有些问题。
所以,除非你对以上两点十分清楚并且可以接受,不然,还是使用官方的FRIEND_TEST要更好一些。
∙因为每一个需要访问私有成员的test都需要在产品代码上加上一项 FRIEND_TEST,这会让你思考:我真的需要访问私有成员吗?有没有不
用访问私有成员的方法?从而帮助形成更好的设计与测试∙因为每一个依赖于实现的test都显式的登记在案,这样当你的实现细节有所改变时,你知道会影响哪些test
∙
∙如何使用gtest测试类的成员函数
∙这两天学习了一下gtest,仅仅是接触到了皮毛,有很多问题还是不怎么明白,不过还是要将自己的一点学习心得与大家分享一下。
∙刚开始学习gtest都是直接使用一些函数,但是在c++中我们最经常用到的是类,那么在单元测试的时候如何测这个类呢?
∙gtest的一个特点是它可以参数化,即产生任意类型的对象,包括基本类型和你的自定义类型。
基本类型很简单,对于自定义类型如何测试呢……∙今天在看关于gmock的一篇文章时突然想到了gtest参数化,之前没有想明白如何测试类。
于是自己就随手写了一个测试程序结果真的通过了。
∙在玩转gtest系列文章中有一篇就是介绍参数化,其中的一个例子类似于:∙class testMyMath:public testing::TestWithParam<MyMath> {
∙};
∙
∙这个类是不需要实现的,当然我的意思是不要添加任何的成员变量和函数,因为你只是测试其他的类。
我的待测类是:
∙class MyMath
{
public:
MyMath(void);
MyMath(int x,int y);
int Add();
int Sub();
int Mul();
int Mod();
~MyMath(void);
private:
int m_x;
int m_y;
};
∙这个类用来实现简单的加减乘除而已。
∙关于参数化不多介绍,因为玩转gtest中介绍的已经蛮好了,何况我还是个菜鸟。
∙接下来:
∙TEST_P(testMyMath,test_Add)
{
MyMath my=GetParam();
EXPECT_EQ(3,my.Add());
}
∙TEST_P(testMyMath,test_Sub)
{
MyMath my=GetParam();
EXPECT_EQ(-1,my.Sub());
}
∙TEST_P(testMyMath,test_Mul)
{
MyMath my=GetParam();
EXPECT_EQ(2,my.Mul());
}
∙TEST_P(testMyMath,test_Mod)
{
MyMath my=GetParam();
EXPECT_EQ(0,my.Mod());
}
∙关于TEST_P这个宏也不介绍,只是要说一点第一个参数一定要是你写的那个用来产生测试类类型的那个类,这里必须是testMyMath,第二个参数的话就是自己起的测试用例的名字了,我感觉英文文档给颠倒了。
∙然后最后一步通过初始化添加测试数据:
∙INSTANTIATE_TEST_CASE_P(Test_MyMath,testMyMath,testing::Values( MyMath(2,1),MyMath(3,4),MyMath(2,2)));
∙
∙ok,然后在运行就可以了。
∙。