因为阅读chromium的需要,想简单学习一下gtest的使用,因为通过chromium的unit_test是了解webkit chromium port的一个途径。其实gtest的相关文章比较多,本文后面的参考文献列出了一些代表性的文章,是学习使用gtest的有价值的资料。
首先看一下逻辑概念:
一个test_program可以包含多个test_case,而一个test_case又可以包含多个test,一个test_program是指一个包含main函数的link unit,也就是一个test_program只能包含一个main函数,和多个test文件,这些test文件中包含多个test_case,而一个test_case又包含多个test。如下图所示:
gtest使用一些宏来判断是否被测试的单元得到期望的结果,宏基本上分为ASSERT_*和EXPECT_*,不同之处是ASSERT_*失败会终止本test的继续执行,而EXPECT_*宏是可以继续执行本test的。比较string是否是空ASSERT_STREQ(NULL, the_string)
如果多个test使用相同的数据,可以使用一个类来共享这些需要共用的数据,这些共享的数据是类的成员变量,这种机制[1]中叫做fixture,fixture拥有SetUp和TearDown函数,用于初始化和析构对象,每个Test执行前都会调用SetUp和TearDown,代码中测试了这种情况。如果使用fixture,那么将使用TEST_F宏替代TEST宏,同时test_case的名字要是fixture类的名字(开始时这个地方犯了错误)。
一个link unit的test program拥有一个main函数,main函数的编写通常如下:
int main(int argc, char **argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
其中RUN_ALL_TEST()函数将运行一个link unit中全部的tests(RUN_ALL_TESTS() runs all tests in your link unit ),需要注意的一点是main函数一定要返回RUN_ALL_TESTS的返回值,否则会出错,即return RUN_ALL_TESTS(),而且RUN_ALL_TESTS()只能被调用1次,否则会引起线程问题。
下面看些具体的例子,假设我有四个文件:my_test.cc、my_test1.cc、my_test2.cc、my_class.h
my_test.cc
#include <gtest/gtest.h>
TEST(MyTestCase, FirstTest) {
EXPECT_EQ(2,2);
}
TEST(MyTestCase, SecondTest) {
EXPECT_EQ(2,2);
}
int main(int argc, char **argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
my_test1.cc#include <gtest/gtest.h>
TEST(MyTestCase, ThirdTest) {
ASSERT_EQ(3,3) << "3 is not equal to 4";
char* p = NULL;
ASSERT_STREQ(NULL, p);
}
TEST(YourTestCase, FirstTest) {
EXPECT_EQ(3,3);
}
my_test2.cc#include <gtest/gtest.h>
#include "my_class.h"
class MyClassTest : public ::testing::Test {
public:
virtual void SetUp() {
my_class_ = new MyClass(10);
}
virtual void TearDown() {
delete my_class_;
}
MyClass* my_class_;
};
TEST_F(MyClassTest, FirstTest) {
EXPECT_EQ(10, my_class_->GetX());
my_class_->SetX(2);
}
TEST_F(MyClassTest, SecondTest) {
EXPECT_EQ(10, my_class_->GetX());
my_class_->SetX(2);
}
my_class.h#include <stdio.h>
class MyClass {
public:
MyClass(int x) : x_(x) {}
void SetX(int x) {
x_ = x;
}
int GetX() const {
return x_;
}
private:
int x_;
};
编译命令如下:
g++ my_test.cc my_test1.cc my_test2.cc -lgtest -lpthread
运行结果
[==========] Running 6 tests from 3 test cases.
[----------] Global test environment set-up.
[----------] 2 tests from MyClassTest
[ RUN ] MyClassTest.FirstTest
[ OK ] MyClassTest.FirstTest (0 ms)
[ RUN ] MyClassTest.SecondTest
[ OK ] MyClassTest.SecondTest (0 ms)
[----------] 2 tests from MyClassTest (0 ms total)
[----------] 3 tests from MyTestCase
[ RUN ] MyTestCase.ThirdTest
[ OK ] MyTestCase.ThirdTest (0 ms)
[ RUN ] MyTestCase.FirstTest
[ OK ] MyTestCase.FirstTest (0 ms)
[ RUN ] MyTestCase.SecondTest
[ OK ] MyTestCase.SecondTest (0 ms)
[----------] 3 tests from MyTestCase (0 ms total)
[----------] 1 test from YourTestCase
[ RUN ] YourTestCase.FirstTest
[ OK ] YourTestCase.FirstTest (0 ms)
[----------] 1 test from YourTestCase (0 ms total)
[----------] Global test environment tear-down
[==========] 6 tests from 3 test cases ran. (0 ms total)
[ PASSED ] 6 tests.
其中参考文献[1]介绍最基础的gtest的使用,参考文献[4]给出了一些gtest使用的举例,参考文献[5]给出了更多的gtest的使用方法(包括:类型测试、参数测试等等)
参考文献:
[1]http://code.google.com/p/googletest/wiki/Primer
[2]https://docs.google.com/present/view?id=dfsbxvm5_0f5s4pvf9
[3]http://www.cnblogs.com/coderzh/archive/2009/04/06/1426755.html