7深入分析gtestWord格式文档下载.docx

上传人:b****6 文档编号:18263644 上传时间:2022-12-14 格式:DOCX 页数:12 大小:257.13KB
下载 相关 举报
7深入分析gtestWord格式文档下载.docx_第1页
第1页 / 共12页
7深入分析gtestWord格式文档下载.docx_第2页
第2页 / 共12页
7深入分析gtestWord格式文档下载.docx_第3页
第3页 / 共12页
7深入分析gtestWord格式文档下载.docx_第4页
第4页 / 共12页
7深入分析gtestWord格式文档下载.docx_第5页
第5页 / 共12页
点击查看更多>>
下载资源
资源描述

7深入分析gtestWord格式文档下载.docx

《7深入分析gtestWord格式文档下载.docx》由会员分享,可在线阅读,更多相关《7深入分析gtestWord格式文档下载.docx(12页珍藏版)》请在冰豆网上搜索。

7深入分析gtestWord格式文档下载.docx

FooTest_Demo_Test(const 

&

);

operator=(const 

};

test_info_ 

internal:

MakeAndRegisterTestInfo( 

"

FooTest"

 

Demo"

(:

GetTestTypeId()),

Test:

SetUpTestCase,

TearDownTestCase,

new 

TestFactoryImpl<

FooTest_Demo_Test>

FooTest_Demo_Test:

TestBody()

switch 

(0)

case 

0:

if 

(const 

AssertionResult 

gtest_ar 

EqHelper<

(sizeof(:

IsNullLiteralHelper

(1)) 

== 

1)>

Compare("

1"

1, 

1)))

;

else 

AssertHelper(

TPRT_NONFATAL_FAILURE,

.\\gtest_demo.cpp"

9,

gtest_ar.failure_message()

) 

Message();

展开后,我们观察到:

1.TEST宏展开后,是一个继承自testing:

Test的类。

2.我们在TEST宏里面写的测试代码,其实是被放到了类的TestBody方法中。

3.通过静态变量test_info_,调用MakeAndRegisterTestInfo对测试案例进行注册。

如下图:

上面关键的方法就是MakeAndRegisterTestInfo了,我们跳到MakeAndRegisterTestInfo函数中:

// 

创建一个 

TestInfo 

对象并注册到 

Google 

Test;

返回创建的TestInfo对象

//

参数:

test_case_name:

 

测试案例的名称

name:

测试的名称

test_case_comment:

测试案例的注释信息

comment:

测试的注释信息

fixture_class_id:

testfixture类的ID

set_up_tc:

事件函数SetUpTestCases的函数地址

tear_down_tc:

事件函数TearDownTestCases的函数地址

factory:

工厂对象,用于创建测试对象(Test)

MakeAndRegisterTestInfo(

char* 

test_case_name, 

name,

test_case_comment, 

comment,

TypeId 

fixture_class_id,

SetUpTestCaseFunc 

set_up_tc,

TearDownTestCaseFunc 

tear_down_tc,

TestFactoryBase* 

factory) 

test_info 

=

TestInfo(test_case_name, 

name, 

fixture_class_id, 

factory);

GetUnitTestImpl()->

AddTestInfo(set_up_tc, 

tear_down_tc, 

test_info);

return 

test_info;

我们看到,上面创建了一个TestInfo对象,然后通过AddTestInfo注册了这个对象。

TestInfo对象到底是一个什么样的东西呢?

TestInfo对象主要用于包含如下信息:

1.测试案例名称(testcasename)

2.测试名称(testname)

3.该案例是否需要执行

4.执行案例时,用于创建Test对象的函数指针

5.测试结果

我们还看到,TestInfo的构造函数中,非常重要的一个参数就是工厂对象,它主要负责在运行测试案例时创建出Test对象。

我们看到我们上面的例子的factory为:

我们明白了,Test对象原来就是TEST宏展开后的那个类的对象(FooTest_Demo_Test),再看看TestFactoryImpl的实现:

template 

<

TestClass>

TestFactoryImpl 

TestFactoryBase 

Test* 

CreateTest() 

TestClass;

这个对象工厂够简单吧,嗯,Simpleisbetter。

当我们需要创建一个测试对象(Test)时,调用factory的CreateTest()方法就可以了。

创建了TestInfo对象后,再通过下面的方法对TestInfo对象进行注册:

GetUnitTestImpl()是获取UnitTestImpl对象:

inline 

UnitTestImpl* 

GetUnitTestImpl() 

UnitTest:

GetInstance()->

impl();

其中UnitTest是一个单件(Singleton),整个进程空间只有一个实例,通过UnitTest:

GetInstance()获取单件的实例。

上面的代码看到,UnitTestImpl对象是最终是从UnitTest对象中获取的。

那么UnitTestImpl到底是一个什么样的东西呢?

可以这样理解:

UnitTestImpl是一个在UnitTest内部使用的,为执行单元测试案例而提供了一系列实现的那么一个类。

(自己归纳的,可能不准确)

我们上面的AddTestInfo就是其中的一个实现,负责注册TestInfo实例:

添加TestInfo对象到整个单元测试中

test_info:

TestInfo对象

AddTestInfo(Test:

test_info) 

处理死亡测试的代码,先不关注它

(original_working_dir_.IsEmpty()) 

original_working_dir_.Set(FilePath:

GetCurrentDir());

if 

printf("

%s\n"

Failed 

to 

get 

the 

current 

working 

directory."

abort();

}

获取或创建了一个TestCase对象,并将testinfo添加到TestCase对象中。

GetTestCase(test_info->

test_case_name(),

test_info->

test_case_comment(),

tear_down_tc)->

AddTestInfo(test_info);

我们看到,TestCase对象出来了,并通过AddTestInfo添加了一个TestInfo对象。

这时,似乎豁然开朗了:

1.TEST宏中的两个参数,第一个参数testcase_name,就是TestCase对象的名称,第二个参数test_name就是Test对象的名称。

而TestInfo包含了一个测试案例的一系列信息。

2.一个TestCase对象对应一个或多个TestInfo对象。

我们来看看TestCase的创建过程(UnitTestImpl:

GetTestCase):

//查找并返回一个指定名称的TestCase对象。

如果对象不存在,则创建一个并返回

//参数:

测试案例名称

TestCase* 

UnitTestImpl:

GetTestCase(const 

test_case_name,

tear_down_tc) 

//从test_cases里查找指定名称的TestCase

internal:

ListNode<

TestCase*>

node 

test_cases_.FindIf(

TestCaseNameIs(test_case_name));

(node 

NULL) 

//没找到,我们来创建一个

TestCase* 

test_case 

new 

TestCase(test_case_name, 

comment, 

set_up_tc, 

tear_down_tc);

//判断是否为死亡测试案例

(internal:

UnitTestOptions:

MatchesFilter(String(test_case_name),

kDeathTestCaseFilter)) 

//是的话,将该案例插入到最后一个死亡测试案例后

node 

test_cases_.InsertAfter(last_death_test_case_, 

test_case);

last_death_test_case_ 

node;

//否则,添加到test_cases最后。

test_cases_.PushBack(test_case);

test_cases_.Last();

//返回TestCase对象

return 

node->

element();

三、回过头看看TEST宏的定义

#define 

TEST(test_case_name, 

test_name)\

GTEST_TEST_(test_case_name, 

test_name, 

\

Test, 

GetTestTypeId())

同时也看看TEST_F宏

TEST_F(test_fixture, 

GTEST_TEST_(test_fixture, 

test_fixture, 

GetTypeId<

test_fixture>

())

都是使用了GTEST_TEST_宏,在看看这个宏如何定义的:

parent_class, 

parent_id)\

GTEST_TEST_CLASS_NAME_(test_case_name, 

test_name) 

parent_class 

{\

test_name)() 

{}\

GTEST_DISALLOW_COPY_AND_ASSIGN_(\

test_name));

=\

MakeAndRegisterTestInfo(\

#test_case_name, 

#test_name, 

(parent_id), 

parent_class:

SetUpTestCase, 

TearDownTestCase, 

test_name)>

test_name):

不需要多解释了,和我们上面展开看到的差不多,不过这里比较明确的看到了,我们在TEST宏里写的就是TestBody里的东西。

这里再补充说明一下里面的GTEST_DISALLOW_COPY_AND_ASSIGN_宏,我们上面的例子看出,这个宏展开后:

正如这个宏的名字一样,它是用于防止对对象进行拷贝和赋值操作的。

四、再来了解RUN_ALL_TESTS宏

我们的测试案例的运行就是通过这个宏发起的。

RUN_ALL_TEST的定义非常简单:

RUN_ALL_TESTS()\

Run())

我们又看到了熟悉的:

GetInstance(),看来案例的执行时从UnitTest的Run方法开始的,我提取了一些Run中的关键代码,如下:

int 

Run() 

__try 

impl_->

RunAllTests();

__except(internal:

GTestShouldProcessSEH(

GetExceptionCode())) 

Exception 

thrown 

with 

code 

0x%x.\nFAIL\n"

GetExceptionCode());

fflush(stdout);

1;

我们又看到了熟悉的impl(UnitTestImpl),具体案例该怎么执行,还是得靠UnitTestImpl。

RunAllTests() 

//...

printer->

OnUnitTestStart(parent_);

计时

TimeInMillis 

start 

GetTimeInMillis();

OnGlobalSetUpStart(parent_);

执行全局的SetUp事件

environments_.ForEach(SetUpEnvironment);

OnGlobalSetUpEnd(parent_);

全局的SetUp事件执行成功的话

(!

HasFatalFailure()) 

执行每个测试案例

test_cases_.ForEach(TestCase:

RunTestCase);

执行全局的TearDown事件

OnGlobalTearDownStart(parent_);

environments_in_reverse_order_.ForEach(TearDownEnvironment);

OnGlobalTearDownEnd(parent_);

elapsed_time_ 

GetTimeInMillis() 

start;

执行完成

OnUnitTestEnd(parent_);

Gets 

result 

and 

clears 

it.

Passed()) 

failed 

true;

ClearResult();

返回测试结果

?

0;

上面,我们很开心的看到了我们前面讲到的全局事件的调用。

environments_是一个Environment的链表结构(List),它的内容是我们在main中通过:

AddGlobalTestEnvironment(new 

FooEnvironment);

添加进去的。

test_cases_我们之前也了解过了,是一个TestCase的链表结构(List)。

gtest实现了一个链表,并且提供了一个Foreach方法,迭代调用某个函数,并将里面的元素作为函数的参数:

typename 

F>

is 

type 

of 

fu

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 解决方案 > 学习计划

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1