使用Google C++ Testing Framework进行C++单元测试_第1页
使用Google C++ Testing Framework进行C++单元测试_第2页
使用Google C++ Testing Framework进行C++单元测试_第3页
使用Google C++ Testing Framework进行C++单元测试_第4页
使用Google C++ Testing Framework进行C++单元测试_第5页
已阅读5页,还剩6页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

使用GoogleC++TestingFramework进行C++单元测试前几个月Google开源了它的测试框架,自称其旗下的上千个项目都在使用它。今天我们就用它来尝尝鲜吧?:-)安装:下载GoogleC++TestingFramework,解压...VC2005:直接打开msvc\gtest.vcproj或msvc\gtest.sln,直接编译即可。Linux/UnixGCC4.0:传统过程:./configuremakeMingw:BCC:用Mingw和BCB6编译需要修改一些代码,文章最后我会把修改过的文件放上来。使用:首先#include<gtest/gtest.h>,当然工程的头文件路径要设置正确1.简单测试TEST假如我写了个函数,是计算阶乘的:1.intFactorial(intn)2.{3.if(n==2)return100;//故意出个错,嘻嘻4.returnn<=0?1:n*Factorial(n-1);5.}6.7./******************************************************8.*TEST:定义一次测试9.*第一个参数是测试用例名,第二个参数是测试名10.*随后的测试结果将以"测试用例名.测试名"的形式给出11.*******************************************************/12.TEST(TestFactorial,ZeroInput)13.{14.//EXPECT_EQ稍候再说,现在只要知道它是测试两个数据是否相等的就行了。15.EXPECT_EQ(1,Factorial(0));16.}17.18.TEST(TestFactorial,OtherInput)19.{20.EXPECT_EQ(1,Factorial(1));21.EXPECT_EQ(2,Factorial(2));EXPECT_EQ(6,Factorial(3));EXPECT_EQ(40320,Factorial(8));22.23.24.}25.26.intmain(intargc,TCHAR*argv[])27.{4.35.36.//用来处理Test相关的命令行开关,如果不关注也可不加testing::InitGoogleTest(&argc,argv);//看函数名就知道干啥了intr=RUN_ALL_TESTS();//只是让它暂停而已,不然一闪就没了std::cin.get();37.//如果全部通过则返回0,否则返回138.returnr;39.}40.//---------------------------------------------------------------------------运行结果:测试框架指出:TestFactorial.ZeroInput运行OK,运行OtherInput时出现三次结果和预期不符。2.多个测试场景需要相同数据配置的情况,用TEST_F1.//用TEST_F做同配置的系列测试2.typedefstd::basic_string<TCHAR>tstring;3.structFooTest:testing::Test{4.5.//这里定义要测试的东东tstringstrExe;6.//可以利用构造、析构来初始化一些参数FooTest(){}7.8.virtual~FooTest(){}2.13.14.//如果构造、析构还不能满足你,还有下面两个虚拟函数virtualvoidSetUp(){//在构造后调用strExe.resize(MAX_PATH);GetModuleFileName(NULL,&strExe[0],MAX_PATH);15.16.17.}virtualvoidTearDown(){}//在析构前调用18.};19.20.//偶写的从完整路径里取出文件名的函数,待测试(路径分隔符假定为'\\')21.tstringgetfilename(consttstring&full)22.{23.returnfull.substr(full.rfind(_T('\\')));24.}25.26.//偶写的从完整路径里取出路径名的函数,待测试(Windows路径)27.tstringgetpath(consttstring&full)28.{29.returnfull.substr(0,full.rfind(_T('\\')));30.}31.32.TEST_F(FooTest,Test_GFN)33.{34.//测试getfilename函数35.EXPECT_STREQ(_T("Project1.exe"),getfilename(strExe).c_str());36.}37.38.TEST_F(FooTest,Test_GP)39.{3.44.}45.//测试getpath函数EXPECT_STREQ(_T("D:\\Code\\libs\\google\\gtest-1.2.1\\BCC_SPC\\bcc\\ex"),getpath(strExe).c_str());46.intmain(intargc,TCHAR*argv[])47.{1.52.53.}//主函数还是一样地testing::InitGoogleTest(&argc,argv);intr=RUN_ALL_TESTS();std::cin.get();returnr;运行结果:瞧,GoogleC++测试框架毫不客气地指出偶的getfilename返回的字符串比预期的多了一个'\\'快速入门:GoogleTest提供了两种断言形式,一种以ASSERT_开头,另一种以EXPECT_开头,它们的区别是ASSERT_*一旦失败立马退出,而EXPECT_*还能继续下去。断言列表:真假条件测试:致命断言非致命断言验证条件ASSERT_TRUE(conditioEXPECT_TRUE(conditicondition为真n);on);ASSERT_FALSE(conditiEXPECT_FALSE(conditicondition为假on);on);数据对比测试:致命断言非致命断言验证条件ASSERT_EQ(期望值,实EXPECT_EQ(期望值,期望值==实际值际值);实际值);ASSERT_NE(val1,val2);EXPECT_NE(val1,val2);val1!=val2ASSERT_LT(val1,val2);EXPECT_LT(val1,val2);val1<val2ASSERT_LE(val1,val2);EXPECT_LE(val1,val2);val1<=val2val1>val2val1>=val2ASSERT_GT(val1,val2);EXPECT_GT(val1,val2);ASSERT_GE(val1,EXPECT_GE(val1,字符串(针对C形式的字符串,即char*或wchar_t*)对比测试:致命断言非致命断言验证条件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_sEXPECT_STRCASEEQ(expected_两个C字符串有相同的内容,忽tr,actual_str);str,actual_str);略大小写ASSERT_STRCASENE(str1,str2);EXPECT_STRCASENE(str1,str2);两个C字符串有不同的内容,忽略大小写TEST宏:TEST宏的作用是创建一个简单测试,它定义了一个测试函数,在这个函数里可以使用任何C++代码并使用上面提供的断言来进行检查。TEST的第一个参数是测试用例名,第二个参数是测试用例中某项测试的名称。一个测试用例可以包含任意数量的独立测试。这两个参数组成了一个测试的全称。就前面的例子来说:我们要测试这个函数:intFactorial(intn);//返回n的阶乘我们的测试用例是:1.测试输入0的情况;2.测试输入其它数据的情况,于是就有了:1.TEST(TestFactorial,ZeroInput){2.EXPECT_EQ(1,Factorial(0));3.}4.5.TEST(TestFactorial,OtherInput){.EXPECT_EQ(1,Factorial(1));EXPECT_EQ(2,Factorial(2));EXPECT_EQ(6,Factorial(3));EXPECT_EQ(40320,Factorial(8));10.}GoogleTest根据测试用例来分组收集测试结果。因此,逻辑相关的测试应该在同一测试用例中;换句话说,它们的TEST()的第一个参数应该是一样的。在上面的例子中,我们有两个测试,ZeroInput和OtherInput,它们都属于同一个测试用例TestFactorial。TEST_F宏:TEST_F宏用于在多个测试中使用同样的数据配置,所以它又叫:测试夹具(TestFixtures)如果我们的多个测试要使用相同的数据(如前例中,我们的Test_GFN和Test_GP都使用程序自身的完整文件名来测试),就可以采用一个测试夹具。要创建测试夹具,只需:1.创建一个类继承自testing::Test。将其中的成员声明为protected:或是public:,因为我们想要从子类中存取夹具成员。2.在该类中声明测试中所要使用到的数据。3.如果需要,编写一个默认构造函数或者SetUp()函数来为每个测试准备对象。4.如果需要,编写一个析构函数或者TearDown()函数来释放你在SetUp()函数中申请的资源。5.如果需要,定义你的测试所需要共享的子程序。当我们要使用夹具时,使用TEST_F()替换掉TEST(),它允许我们存取测试固件中的对象和子程序:1.TEST_F(test_case_name,test_name){2....testbody...3.}与TEST()一样,第一个参数是测试用例的名称,但对TEST_F()来说,这个名称必须与测试夹具类的名称一样。对于TEST_F()中定义的每个测试,GoogleTest将会:1.创建一个全新的测试夹具2.通过SetUp()初始化它,3.运行测试4.调用TearDown()来进行清理工作5.删除测试夹具。注意,同一测试用例中,不同的测试拥有不同的测试夹具。GoogleTest不会对多个测试重用一个测试夹具,测试对测试夹具的改动并不会影响到其他测试。调用测试TEST()和TEST_F()向GoogleTest隐式注册它们的测试。因此,与很多其他的C++测试框架不同,你不需要为了运行你定义的测试而将它们全部再列出来一次。在定义好测试后,你可以通过RUN_ALL_TESTS()来运行它们,如果所有测试成功,该函数返回0,否则会返回1.注意RUN_ALL_TESTS()会运行你链接到的所有测试——它们可以来自不同的测试用例,甚至是来自不同的文件。当被调用时,RUN_ALL_TESTS()宏会:1.保存所有的GoogleTest标志。2.为一个测试创建测试夹具对象。3.调用SetUp()初始化它。4.在固件对象上运行测试。5.调用TearDown()清理夹具。6.删除固件。7.恢复所有GoogleTest标志的状态。8.重复上诉步骤,直到所有测试完成。此外,如果第二步时,测试夹具的构造函数产生一个致命错误,继续执行3至5部显然没有必要,所以它们会被跳过。与之相似,如果第3部产生致命错误,第4部也会被跳过。重要:你不能忽略掉RUN_ALL_TESTS()的返回值,否则gcc会报一个编译错误。这样设计的理由是自动化测试服务会根据测试退出返回码来决定一个测试是否通过,而不是根据其stdout/stderr输出;因此你的main()函数必须返回RUN_ALL_TESTS()的值。而且,你应该只调用RUN_ALL_TESTS()一次。多次调用该函数会与GoogleTest的一些高阶特性(如线程安全死亡测试thread-safedeathtests)冲突,因而是不被支持的。编写main()函数你可以从下面这个模板开始:1.#include"this/package/foo.h"2.#include<gtest/gtest.h>3.namespace{.8.9.//用于测试Foo类的测试夹具classFooTest:publictesting::Test{protected://下面四个方法如果没有代码的话的可以不用定义FooTest(){//这里可以为每个测试做一些设置工作2.23.24.}virtual~FooTest(){//可以做一些不会抛出异常的清理工作}//如果构造和析构还不能满足你的设置、清理工作//你还可以在下面两个函数里做这些virtualvoidSetUp(){//这里的代码在构造之后(在每次测试之前)马上执行}virtualvoidTearDown(){//这里的代码在每次测试之后(在析构之前)马上执行}//可以在这里定义所有要用到Foo的测试用例中所需要的对象.};//测试做Abc操作的Foo::Bar()方法.4.TEST_F(FooTest,MethodBarDoesAbc){conststring

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论