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
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
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
struct A
{
virtual int Method1(bool b) = 0;
}
模拟后:
struct MockA : public A
{
MOCK_METHOD1(Method1, int(bool b));
}
这样就Mock好了,只要在程序中生成一个MockA的实例就可以调用了。
它只能用在模拟类中,起模拟方法的作用,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
一般在用到这些宏之前,我们都要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
转载请注明!