GTest && GMock

GTest和GMock简介

 Google开源C++单元测试框架的简称为GTest,其下载地址为:http://code.google.com/p/googlemock/downloads/list (下载是Gmock,但其中已包含Gtest)。它支持的操作系统为Windows/Linux/Unix,支持的编译器为:VC.Net/gcc4.0(及以上版本),Mingw(据说需修改一些源码),BCB6(据说需修改一些源码)。GMock是GTest的衍生品,类似jMock和EasyMock,目的是快速地做出一个接口的仿制品。

 

如何使用Gtest及Gmock
1. 根据选择使用的编译器build Gtest和Gmock(这儿选择VC2008)

2. 设置好头文件和导入库文件

    Gtest头文件及导入库文件:gtest.h gtestd.lib

    Gmock头文件及导入库文件:gmock.h gmock.lib

 

使用GTest写Case

a) 写个简单的测试

1. 被测函数 example:

int Factorial( int n )

{

      if(n==2) return 100; //故意出个错,嘻嘻

      return n<=0? 1 : n*Factorial(n - 1);

}

2.  利用TEST宏写case 根据上述示例:

TEST(TestFactorial, ZeroInput) 

{

    //EXPECT_EQ稍候再说,现在只要知道它是测试两个数据是否相等的就行了。

    EXPECT_EQ(1, Factorial(0));

}

 

TEST(TestFactorial, OtherInput)

{

    EXPECT_EQ(1, Factorial(1));

    EXPECT_EQ(2, Factorial(2));

    EXPECT_EQ(6, Factorial(3));

    EXPECT_EQ(40320, Factorial(8));

3. 在主函数中根据上述示例:

int main()

  testing::InitGoogleTest(&argc,argv); 

  int r = RUN_ALL_TESTS(); 

  getchar();

  return r;

}

b) 多个测试场景需要相同数据配置的情况,用TEST_F

1.从testing::Test 派生一个类,example:FooTest 
2.在该FooTest中可存储多个测试中需要用到的同一份数据

  I) 构造中或SetUp()中设置数据

      II) 析构中或TearDown()清理数据(若需要)

3. 使用TEST_F代替TEST

    记住TEST_F的第一参数必须跟刚才派生的那个FooTest一致

example(参考http://www.cppprog.com/2009/0101/28.html):

//用TEST_F做同配置的系列测试 
typedef std::basic_string<TCHAR> tstring; 
struct FooTest : testing::Test { 
    //这里定义要测试的东东 
    tstring strExe; 
    //可以利用构造、析构来初始化一些参数 
    FooTest() {} 
    virtual ~FooTest() {} 
 
    //如果构造、析构还不能满足你,还有下面两个虚拟函数 
    virtual void SetUp() { 
        // 在构造后调用 
        strExe.resize(MAX_PATH); 
        GetModuleFileName(NULL, &strExe[0], MAX_PATH); 
    } 
 
    virtual void TearDown() { }   // 在析构前调用 
}; 
 
//偶写的从完整路径里取出文件名的函数,待测试(路径分隔符假定为'\\') 
tstring getfilename(const tstring &full)   
{ 
    return full.substr(full.rfind(_T('\\'))); 
} 
 
//偶写的从完整路径里取出路径名的函数,待测试(Windows路径) 
tstring getpath(const tstring &full)  
{ 
    return full.substr(0, full.rfind(_T('\\'))); 
} 
 
TEST_F(FooTest, Test_GFN)  
{ 
    //测试getfilename函数 
    EXPECT_STREQ(_T("Project1.exe"), getfilename(strExe).c_str()); 
} 
 
TEST_F(FooTest, Test_GP)  
{ 
    //测试getpath函数 
    EXPECT_STREQ( 
            _T("D:\\Code\\libs\\google\\gtest-1.2.1\\BCC_SPC\\bcc\\ex"), 
            getpath(strExe).c_str()); 
} 
 
int main(int argc, TCHAR* argv[])   
{ 
    //主函数还是一样地 
    testing::InitGoogleTest(&argc,argv); 
    int r = RUN_ALL_TESTS(); 
    std::cin.get(); 
    return r; 
}

Gtest中常用的断言

•ASSERT_系列

  example:

   ASSERT_TRUE、 ASSERT_EQ、 ASSERT_STREQ

•EXPECT_系列(与ASSERT_系列对应)

   EXPECT_FALSE、 EXPECT_NE、 EXPECT_STRNE

ASSERT_系列与EXPECT_系列的不同是:ASSERT_系列遇到条件不成立时不再往下跑,而EXPECT_系列则不管条件成立与否,都放行程序继续往下跑

下面说说Gmock
•用意:王五写好了代码,中间引用了张三提供的接口,张三现在还未写好实现,王五要测自己写的代码怎么办?这时Gmock就派上用场了。
•怎样模拟?很简单。模拟接口example:

  struct A

  {

  virtual int Method1(bool b) = 0;

  }

  模拟后:

  struct  MockA : public A

  {

    MOCK_METHOD1(Method1,  int(bool b)); 

  }

  这样就Mock好了,只要在程序中生成一个MockA的实例就可以调用了。

•关于MOCK_METHOD宏

  它只能用在模拟类中,起模拟方法的作用,MOCK_METHOD0表示该方法没有参数,MOCK_METHOD1表示1参数

•接口较长不麻烦

  a) 安装Python2.4以上3.0以下版本

  b) 利用gmock安装目录下scripts\generator\gmock_gen.py,在命令行中输入:gmock_gen.py C:\A.h >> C:\MokckA.h就可以生成,不了解可以查看README

•EXPECT_CALL,我认为最常用,后面可以跟很多点点修饰,比如说:Times(n),表示预期执行几次;WillOnce(Return(0)),表示返回0的次数仅为1次;WillRepeatedly(Return(1)),表示返回为1的次数将会重复等等, EXPECT_CALL规定必须放在case函数的前面
 
•其他诸如EXPECT_TRUE、EXPECT_EQ等条件判断也经常被用到

一般在用到这些宏之前,我们都要using一下,例如:using testing::Return; using testing::DefaultValue;using testing::Eq; 等等 

•EXPECT_CALL默认在函数中是反着来的,比如:

using testing::_;... 

EXPECT_CALL(Program, Code(_));  // #1 

EXPECT_CALL(Program, Design(1))  // #2 

  .Times(1);

是先对比#2再对比#1的。如果想严格按照指定顺序执行,那么可以:

using testing::InSequence; ...

TEST(TestSuitName, Testcase1) 

 { 

    InSequence dummy; 

    EXPECT_CALL(Program, Design(1)); 

    EXPECT_CALL(Program, Code()); 

    EXPECT_CALL(Program, UnitTest()); 

 } 

 Fun(); 

}

更详细的可以参考:http://www.cppprog.com/2009/0410/103.html 中的“序列”说明

 

最后,如果觉得在控制台查看结果太别扭或不方便,那么,可以在

testing::InitGoogleTest(&argc,argv);

之前添加如下语句,可方便输出到指定路径xml文件:

 testing::FLAGS_gtest_output = "xml:d:\\output.xml";  // 输出到d:\output.xml
 testing::FLAGS_gtest_filter = "TestSuitName.TestCase?-TestSuitName.TestCase1"; // 除了TestSuitName这个test suit下的TestCase1,其他以TestCase开头后面只跟一个字符的test case都需要测试

 

参考:http://www.cppprog.com/2009/0101/29.html

http://www.cppprog.com/2009/0410/103.html

http://www.cppprog.com/2009/0101/28.html

http://www.kuqin.com/testing/20090413/45436.html

 转载请注明!

 

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值