google test初步分析
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
google test初步分析
现在常用的C++单元测试框架有CppUnit,CxxTest,boost::test和google test。不像java/C#的测试框架,由于C++不支持reflection,所以,必须要做一些额外的工作,让框架知道相关内容的存在。CppUnit 的做法是用宏进行注册。这种做法要求我们每添加一个测试,就要考虑用相应的宏进行注册,这种做法很繁琐,最大的问题在于由于疏忽而遗漏,这种靠人工保证的东西不可靠。在这点上,CxxTest做得要好一些,有一个专门的脚本做这件事。通过这个脚本扫描这个自己编写的文件,生成一些新的文件,完成这个工作。从代码的表现力和可靠度来说,要好得多。唯一的问题是引入了一个脚本,而且这个脚本一般是由某些动态语言写成的(目前的CxxTest有Perl和Python的脚本),从而引入了对这种语言的依赖。而boost::test和google test 则是通过一些宏机制,来实现用户只需写一次就可以自动完成注册。
我大概分析了一下gtest的实现机制。由于里面用了很多宏,比较费解,因此首先用cl /P /C命令将之展开,我的测试程序如下
#include
TEST(FactorialTest, Negative) {
EXPECT_EQ(1, 1);
}
宏展开完后主要部分如下
class FactorialTest_Negative_Test : public ::testing::Test {
public: FactorialTest_Negative_Test() {}
private: virtual void TestBody();
static ::testing::TestInfo* const test_info_;
FactorialTest_Negative_Test(const FactorialTest_Negativ e_Test &);
void operator=(const FactorialTest_Negative_Test &); };
//init test_info_
::testing::TestInfo* const FactorialTest_Negative_Test ::te st_info_ = ::testing::internal::MakeAndRegisterTestInfo( "F actorialTest", "Negative", "", "", (::testing::internal::GetTest TypeId()), ::testing::Test::SetUpTestCase, ::testing::Test:: TearDownTestCase, new ::testing::internal::TestFactoryImp l< FactorialTest_Negative_Test>);
void FactorialTest_Negative_Test::TestBody() {
// This test is named "Negative", and belongs to the "Fact orialTest"
// test case.
switch (0) case 0: if (const ::testing::AssertionResult gte st_ar = (::testing::internal:: EqHelper<(sizeof(::testing::int ernal::IsNullLiteralHelper(1)) == 1)>::Compare("1", "Factor ial(-5)", 1, Factorial(-5)))) ; else ::testing::internal::AssertH elper(::testing::TPRT_NONFATAL_FAILURE, "sample1_unitte ", 82, gtest_ar.failure_message()) = ::testing::Message ();
}
可以看出,gtest是利用static变量的初始化来实现函数注册的,主要函数为MakeAndRegisterTestInfo(),该函数定义在src\ 里面
TestInfo* MakeAndRegisterTestInfo(
const char* test_case_name, const char* name,
const char* test_case_comment, const char* comment, TypeId fixture_class_id,
SetUpTestCaseFunc set_up_tc,
TearDownTestCaseFunc tear_down_tc,
TestFactoryBase* factory)
{
TestInfo* const test_info =
new TestInfo(test_case_name, name, test_case_comm ent, comment,
fixture_class_id, factory);
GetUnitTestImpl()->AddTestInfo(set_up_tc, tear_down_t c, test_info); //关键是这一行
return test_info;
}
果然不出所料,GetUnitTestImpl()->AddTestInfo(xx)这一句就是做注册,下面我仿照gtest自己写了一个简单的测试框架
#include
#include
#include
using namespace std;
class Test