百度博客总是出问题,鸡肋,弃之!好坏我也是新浪6年用户,想想也改为新浪做贡献……
前几篇文章参见 hi.baidu.com/jsmlay/blog
因为之前因为其他事情中断了项目的学习,而且换了电脑(P4,1G,泪奔)所以要重新安装gtest……
最新的gtest版本为1.6,新版本发生了变化,首先安装了VS2010,按照【玩转Google开源C++单元测试gtest (1)】原文,或者本博客的【玩转Google开源C++单元测试gtest(1)】的原文进行配置……有点差别,gtest-1.6根目录下没有了gtestd.lib(以前就没有?),如果你也找不到,用下面方法解决:
首先打开msvc文件夹下的工程文件gtest-md.sln(如果是linux系统,或者其他编程工具的用户参与gtest原文,是对应不同的文件夹),然后将其中的gtest工程设为启动项,按应该配置的方法进行配置(应该是三步,因为少gtestd.lib,所以是两步),编译执行,执行结果肯定是出错的,但没事,gtestd.lib已经放置在gtest-1.6/msvc下了,有了gtestd.lib,所有配置所需的文件就全了,把gtestd.lib放置在C:/lib下(为了少写路径),然后退出刚刚打开的工程,新建工程,按照原文的三步配置就OK了……有问题请在http://hi.baidu.com/jsmlay/home留言……
下面进行死亡测试:
1.了解死亡测试
ASSERT_DEATH(statement, regex`);
EXPECT_DEATH(statement, regex`);
首先新建一个空测试,这个死亡测试实际上没有任何被测语句,只是走了一遍死亡测试的流程,代码如下:
#include <gtestgtest.h>
#include <stdlib.h>
#include <tchar.h>
void Foo()
{
}
TEST(MyDeathTest, TestTwo) {
// This test is run in the "fast"style:
ASSERT_DEATH(Foo(),"");//如果想测试该句完成后继续执行后面的测试语句请用EXPECT_DEATH(Foo(),""),测试Foo(),如果Foo()死亡,且原因为””,则测试通过(这句的意思是预期死亡,而不是预期成功),如果测Foo未死亡,则返回测试失败,这里显然是失败
}
int main(int argc,char** argv) {
testing::InitGoogleTest(&argc,argv);//初始化谷歌测试
testing::FLAGS_gtest_death_test_style = "fast";//设定谷歌测试模式
int flag = RUN_ALL_TESTS();//执行TEST(MyDeathTest, TestTwo) 定义标识接受返回值
system("pause"); //防止控制台窗口一闪而过
return flag;
}
以上测试在命名为MyDeathTest中进行了名为TestTwo的测试,测试的执行结果如下:
因为Foo为空,所以不会死亡,所以预期要死亡的没有死亡,测试失败,失败原因为failed to die,Error Msg为””……
下面测试一个应该死亡的:在foo中添加两句话并进行测试
#include <gtestgtest.h>
#include <stdlib.h>
#include <tchar.h>
void Foo()
{
int *pInt = 0;
*pInt = 42 ;
}
TEST(MyDeathTest, Test) {
// This test is run in the "fast"style:
ASSERT_DEATH(Foo(),"");
}
int main(int argc,char** argv) {
testing::InitGoogleTest(&argc, argv);
testing::FLAGS_gtest_death_test_style = "fast";
int flag = RUN_ALL_TESTS();
system("pause");
return flag;
}
测试结果为:
程序死亡,测试成功!
ASSERT_EXIT(statement, predicate, regex`);
EXPECT_EXIT(statement, predicate, regex`);
这两句测试退出的效果,ASSERT退出后不继续执行后面的语句,EXPECT则继续执行后面的语句(这种情况是可能发生的)
因为对退出时的代码有要求,所以这里用windows的_exit(int)作为被测函数,这个函数兼有退出效果并能控制退出代码……
测试示例如下:
#include <gtestgtest.h>
#include <stdlib.h>
#include <tchar.h>
TEST(ExitDeathTest, Demo)
{
EXPECT_EXIT(_exit(1),testing::ExitedWithCode(1), "");//这句话的意思是,当_exit(1)一句(或者是被测单元,被测模块etc.)退出时,并且退出的代码为1(testing::ExitedWithCode(1)),并且退出的stderr消息为”” 三个条件同时达成时,测试成功,否则,测试失败
}
int main(int argc,char** argv) {
testing::InitGoogleTest(&argc, argv);
testing::FLAGS_gtest_death_test_style = "fast";
int flag = RUN_ALL_TESTS();
system("pause");
return flag;
}
成功执行结果为:
当预期退出码改为2时,ExitedWithCode(2),测试失败的结果为:(注意错误原因为died but not with expected exit code: Exited withexit status 1)
当预期stderr消息改为其他时(最后的参数改为”这里写你预期的stderr”),错误结果为:在结果中可以看到,实际为(Actual msg:)为空,而预期(Expected:)为这里写你预期的stderr
*_DEBUG_DEATH
首先解释原文贴出的debug定义:
#ifdefNDEBUG//如果没有定义DEBUG,也就是你被测程序的版本为发行版
#defineEXPECT_DEBUG_DEATH(statement,regex)
do{statement;}while(false)
//定义EXPECT_DEBUG_DEATH(statement,regex)这个语句的实际执行体为
//do{
//statement
//}while(false)
//你会发现,这个执行体没有抛出异常的语句,完……
#defineASSERT_DEBUG_DEATH(statement,regex)
do{statement;}while(false)
//类似上面
#else //如果定义了DEBUG,也就是你被测程序的版本为测试版
#defineEXPECT_DEBUG_DEATH(statement,regex)
EXPECT_DEATH(statement,regex)
// 执行EXPECT_DEBUG_DEATH(statement,regex)一句时实际执行的是
//EXPECT_DEATH(statement,regex)这句上文说过,你懂的!这句抛出了异常
#defineASSERT_DEBUG_DEATH(statement,regex)
ASSERT_DEATH(statement,regex)
//类似上面
#endif//NDEBUGforEXPECT_DEBUG_DEATH
所以EXPECT _DEBUG_DEATH和ASSERT _DEBUG_DEATH在测试版下就是EXPECT_DEATH和ASSERT_DEATH应该没有异议
下面测试原文的例子:
发布版的程序需要的方法是这样写的:
int DieInDebugElse12(int* sideeffect) {
if (sideeffect) *sideeffect = 12;
return 12;
}
但是在程序还处于调试阶段的时候,会加很多调试相关的语句,但是程序员们不可能在完成整个庞大的程序之后再来删除这些调试语句,所以会使用#ifndef NDEBUG#endif来包含这些语句,并在程序文件整体上标注(#define NDEBUG),这样程序中所有的调试语句都将执行,当测试完毕发布的时候,只需删掉(#define NDEBUG),虽然没删掉里面的调试语句,这些调试语句也将不再执行,所以一个调试阶段的语句是以下的情况:
int DieInDebugElse12(int* sideeffect) {
if (sideeffect) *sideeffect =12;
#ifndef NDEBUG
GTEST_LOG_(FATAL, "debug death insideDieInDebugElse12()");
#endif // NDEBUG
return 12;
}
现在我们测试的就是这个程序片段:
#include <gtestgtest.h>
#include <stdlib.h>
#include <tchar.h>
#define NDEBUG//在这里定义了NDEBUG
int DieInDebugElse12(int* sideeffect) {
if (sideeffect) *sideeffect =12;
#ifndef NDEBUG
GTEST_LOG_(FATAL, "debug death insideDieInDebugElse12()");//因为定义了NDEBUG,所以这句被屏蔽,相当于没有
#endif // NDEBUG
return 12;
}
TEST(TestCase,TestDieOr12WorksInDgbAndOpt)
{
int sideeffect = 0;
// Only asserts indbg.
EXPECT_DEBUG_DEATH(DieInDebugElse12(&sideeffect),"death");//实际执行的是do { DieInDebugElse12(0); } while(false)
#ifdef NDEBUG
// opt-mode has sideeffectvisible.
EXPECT_EQ(12, sideeffect);
#else
// dbg-mode no visiblesideeffect.
EXPECT_EQ(0, sideeffect);//因为定义了NDEBUG,所以这句被屏蔽,相当于没有
#endif
}
int main(int argc,char** argv) {
testing::InitGoogleTest(&argc, argv);
testing::FLAGS_gtest_death_test_style = "fast";
int flag = RUN_ALL_TESTS();
system("pause");
return flag;
}
按照定义了NDEBUG的程序进行测试,程序正常执行,不会有任何错误,DieInDebugElse12()不会死亡,测试(期望程序死亡)失败,测试的结果如下图所示:
注意,这里失败的原因是:failed to die,被测方法没有死亡……
现在删掉#defineNDEBUG,重新进行测试,如下:
#include <gtestgtest.h>
#include <stdlib.h>
#include <tchar.h>
int DieInDebugElse12(int* sideeffect) {
if (sideeffect) *sideeffect =12;
#ifndef NDEBUG
GTEST_LOG_(FATAL, "debug death insideDieInDe bugElse12()");
#endif // NDEBUG
return 12;
}
TEST(TestCase,TestDieOr12WorksInDgbAndOpt)
{
int sideeffect = 0;
// Only asserts indbg.
EXPECT_DEBUG_DEATH(DieInDebugElse12(&sideeffect),"death");//实际执行的是EXPECT_DEATH(DieInDebugElse12(0), "");
#ifdef NDEBUG
// opt-mode has sideeffectvisible.
EXPECT_EQ(12, sideeffect);//因为没有定义NDEBU,该句相当于没写
#else
// dbg-mode no visiblesideeffect.
EXPECT_EQ(0, sideeffect);
#endif
}
int main(int argc,char** argv) {
testing::InitGoogleTest(&argc, argv);
testing::FLAGS_gtest_death_test_style = "fast";
int flag = RUN_ALL_TESTS();
system("pause");
return flag;
}
测试的结果因为DieInDebugElse12(0)的死亡而测试通过: