Google Test 主页:http://code.google.com/p/googletest/ 教程:http://code.google.com/p/googletest/wiki/V1_6_Documentation ASSERT_* 一旦失败立即退出当前函数,EXPECT_* 还能继续下去。
针对C形式的字符串,即char*或wchar_t*对比测试:
下面的断言允许你自己选择可接受的误差范围:
ASSERT_THROW(Foo(5), bar_exception);
EXPECT_NO_THROW({ int n = 5; Bar(&n); }); 用户可以根据需求自定义断言:
最多支持5个参数 //判断是否互质 bool MutuallyPrime(int m, int n) { ... } const int a = 3; const int b = 4; const int c = 10; EXPECT_PRED2(MutuallyPrime, a, b); EXPECT_PRED2(MutuallyPrime, b, c); MutuallyPrime(a, b) is true, where a is 3 b is 4 MutuallyPrime(b, c) is false, where b is 4 c is 10 用户可以自定义谓语断言的输出流:
pred_format采用的是如下函数形式: /** * @brief PredicateFormattern pred_format函数 * * @param expr1 val1的名称 * @param expr2 val2的名称 * @param exprn valn的名称 * @param val1 参数val1 * @param val2 参数val2 * @param valn 参数valn * * @return 返回类型为test::AssertionResult */ testing::AssertionResult PredicateFormattern( const char* expr1, const char* expr2, ... const char* exprn, T1 val1, T2 val2, ... Tn valn); test::AssertionResult的返回类型有两个值如下: namespace testing { //成功 AssertionResult AssertionSuccess(); //失败 AssertionResult AssertionFailure(const Message& msg); } 作为例子,我们来改善前面使用EXPECT_PRED2()的那个例子里的失败信息: //求最小公约数 int SmallestPrimeCommonDivisor(int m, int n) { ... }
//自己声明pre_format()的例子 testing::AssertionResult AssertMutuallyPrime(const char* m_expr, const char* n_expr, int m, int n) //前两个是参数名称:a,b 后面两个是a和b的传入值 { //判断互质 if (MutuallyPrime(m, n)) return testing::AssertionSuccess();//返回成功 //定义了一个testing::Message来打印出错信息 testing::Message msg; //自己定义的出错格式 msg << m_expr << " and " << n_expr << " (" << m << " and " << n << ") are not mutually prime, " << "as they have a common divisor " << SmallestPrimeCommonDivisor(m, n); return testing::AssertionFailure(msg);//返回失败,并传入出错信息作为参数 }
//调用方法 EXPECT_PRED_FORMAT2(AssertMutuallyPrime, b, c); 打印结果: b and c (4 and 10) are not mutually prime, as they have a common divisor 2 任何检查程序是否按预期退出的测试:
statement是一个可能造成进程死亡的程序段。 · 如: bool f(), true 或 a==b Google Test自带了两种判断进程结束的断言函数,返回值为bool,只接受一个int参数: testing::ExitedWithCode(exit_code); testing::KilledBySignal(signal_number); TEST(MyDeathTest, Foo) { // This death test uses a compound statement. ASSERT_DEATH({ int n = 5; Foo(&n); }, "Error on line .* of Foo()"); } TEST(MyDeathTest, NormalExit) { //testing::ExitedWithCode(exit_code)返回码必须一致才算测试成功 EXPECT_EXIT(NormalExit(), testing::ExitedWithCode(0), "Success"); } TEST(MyDeathTest, KillMyself) { //testing::KilledBySignal(signal_number)杀死进程的信号必须一致才算测试成功 EXPECT_EXIT(KillMyself(), testing::KilledBySignal(SIGKILL), "Sending myself unblockable signal"); } 检验项目: · Foo(5) 使进程死亡并得到指定的信息。 · NormalExit() 使进程打印”Success” 到stderr并且退出码为0。 · KillMyself() 使用信号 SIGKILL 杀死进程。 Death断言只适用于Linux Windows的HRESULT断言 这些断言用于测试HRESULT成功或失败:
HRESULT断言只适用于windows 测试用例main函数,头文件只要包含gtest/gtest.h即可: #include <iostream>
#include "gtest/gtest.h"
GTEST_API_ int main(int argc, char **argv) { std::cout << "Running main() from gtest_main.cc\n";
testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } 简单测试用例 TEST(test_case_name, test_name){} 第一个参数是测试用例名称,第二个参数是一个该用例中的测试名称。 #include "gtest/gtest.h"
TEST(TestFactorial, ZeroInput) { 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)); } TEST_F(test_fixture, test_name){} 第一个参数测试夹具名称,第二个参数测试该测试夹具中的一个测试名称。 #include "gtest/gtest.h"
// 用于测试Foo类的测试夹具,继承类testing::Test class FooTest : public ::testing::Test { protected: // 在该测试用例的第一个测试开始前调用 static void SetUpTestCase() { shared_resource_ = new ...; }
// 在该测试用力的最后一个测试结束后调用 static void TearDownTestCase() { delete shared_resource_; shared_resource_ = NULL; }
// 如果构造和析构还不能满足你的设置、清理工作 // 你还可以在下面两个函数里做这些 virtual void SetUp() { ... } virtual void TearDown() { ... }
static T* shared_resource_; };
T* FooTest::shared_resource_ = NULL;
TEST_F(FooTest, Test1) { ... you can refer to shared_resource here ... } TEST_F(FooTest, Test2) { ... you can refer to shared_resource here ... } 值参数测试: class FooTest : public ::testing::TestWithParam<const char*> { // 通过调用函数GetParam()来获取模板类型的值 // 如:该类const char*模版类型的值 // 具体取值见下面的INSTANTIATE_TEST_CASE_P() };
//如果想对已有的测试夹具加上值参数测试如下: class BaseTest : public ::testing::Test { ... }; class BarTest : public BaseTest, public ::testing::WithParamInterface<const char*> { ... }; TEST_P(CaseName, TestName){} 第一个参数测试夹具名称,第二个参数测试该测试夹具中的一个测试名称。 TEST_P(FooTest, DoesBlah) { // 可以直接访问GetParam()函数来获取值参数 // 如:该类const char*模版类型的值 // 具体取值见下面的INSTANTIATE_TEST_CASE_P() EXPECT_TRUE(foo.Blah(GetParam())); ... }
TEST_P(FooTest, HasBlahBlah) { ... } INSTANTIATE_TEST_CASE_P(InstantiationName, CaseName, ValuesPred); 第一个参数实例化名称
Combine也可以通过定义宏使其生效: INSTANTIATE_TEST_CASE_P(InstantiationName, FooTest, ::testing::Values("meeny", "miny", "moe")); // 上面的GetParam()取值为"meeny", "miny", "moe"三个进行测试。
const char* pets[] = {"cat", "dog"}; INSTANTIATE_TEST_CASE_P(AnotherInstantiationName, FooTest, ::testing::ValuesIn(pets)); // GetParam()从数组中进行取值 模版类型测试: //模版类型测试夹具 template <typename T> class FooTest : public ::testing::Test { public: ... typedef std::list<T> List; static T shared_; T value_; }; TYPED_TEST_CASE(CaseName, Types){} 第一个参数夹具即测试用例名称,第二个参数Types<> //该测试模块是否可用 #if GTEST_HAS_TYPED_TEST
typedef ::testing::Types<char, int, unsigned int> MyTypes; //初始化所有模版类型,必须要有的 //相当于测试了FooTest<char>,FooTest<int>和FooTest<unsigned int>三个类 TYPED_TEST_CASE(FooTest, MyTypes); TYPED_TEST(CaseName, TestName){} 第一个参数夹具即测试用例名称,第二个参数该用例中的某一个测试名称 TYPED_TEST(FooTest, DoesBlah) {
//通过TypeParam来获得模版类型 TypeParam n = this->value_;
n += TestFixture::shared_;
//型别重命名 typename TestFixture::List values; values.push_back(n); ... }
#endif // GTEST_HAS_TYPED_TEST 模版类型参数测试: template <typename T> class FooTest : public ::testing::Test { ... }; TYPED_TEST_CASE_P(FooTest); 只有一个参数测试夹具名称 TYPED_TEST_P(CaseName, TestName){} 第一个参数夹具即测试用例名称,第二个参数该用例中的某一个测试名称 TYPED_TEST_P(FooTest, DoesBlah) { //同上也是通过TypeParam来获得模版类型 TypeParam n = 0; ... }
TYPED_TEST_P(FooTest, HasPropertyA) { ... } // 在实例化之前,告诉测试系统需要注册的用例和实际测试 // REGISTER_TYPED_TEST_CASE_P(CaseName, TestName1, TestName2, ...) REGISTER_TYPED_TEST_CASE_P(FooTest, DoesBlah, HasPropertyA); // 实力化测试的模板类型 typedef ::testing::Types<char, int, unsigned int> MyTypes; INSTANTIATE_TYPED_TEST_CASE_P(InstantiateName, FooTest, MyTypes);
//如果只有一个类型的化也可以直接填 INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, int); 个人感觉和TYPED_TEST测试作用很相似,只不过一个实例化类型在前一个在后。 友元测试,用来测试类的似有成员: // foo.h #include "gtest/gtest_prod.h"
// 待测试的类 class Foo { ... private: //定义友元测试的用例和测试 FRIEND_TEST(FooTest, BarReturnsZeroOnNull); int Bar(void* x); };
// foo_test.cc // 用例和测试名一致 TEST(FooTest, BarReturnsZeroOnNull) { Foo foo; // 可以使用私有成员变量了 EXPECT_EQ(0, foo.Bar(NULL)); } 夹具测试使用FRIEND_TEST的例子: // foo.h namespace my_namespace {
class Foo { friend class FooTest; FRIEND_TEST(FooTest, Bar); FRIEND_TEST(FooTest, Baz); ... definition of the class Foo ... };
} // namespace my_namespace
// foo_test.cc namespace my_namespace { class FooTest : public ::testing::Test { protected: ... };
TEST_F(FooTest, Bar) { ... } TEST_F(FooTest, Baz) { ... }
} // namespace my_namespace namespace testing {
class TestInfo { public: // 测试用例名称 const char* test_case_name() const;
// 测试名称 const char* name() const;
// 模板类型名称,主要用在TYPED_TEST和TYPED_TEST_P中 const char* type_param() const;
// 值参数名称,主要用在TEST_P中 const char* value_param() const;
};
} TEST(CaseName, TestName) { const ::testing::TestInfo* const test_info = ::testing::UnitTest::GetInstance()->current_test_info(); printf("We are in test %s of test case %s.\n", test_info->name(), test_info->test_case_name()); }
//打印结果: //We are in test TestName of test case CaseName. 断言的测试结果: class TestPartResult { public: // explicit SUCCEED(), FAIL(), or ADD_FAILURE()). enum Type { kSuccess, // 成功 kNonFatalFailure, // 非致命断言失败,但是测试可以继续EXPECT_*断言失败时返回结果 kFatalFailure // 致命断言失败,但是测试无法继续ASSERT_*断言失败时返回结果 }; // 返回测试断言结果 Type type() const;
// 断言所在文件名 const char* file_name() const;
// 断言所在行号 int line_number() const;
// 失败信息概要 const char* summary() const;
// 这部分测试关联的消息 const char* message() const;
// 返回测试是否成功,true表示成功 bool passed() const { return type_ == kSuccess; }
// 返回测试是否失败,true表示失败 bool failed() const { return type_ != kSuccess; }
// 返回测试是否为非致命断言失败 bool nonfatally_failed() const { return type_ == kNonFatalFailure; }
// 返回测试是否为致命断言失败 bool fatally_failed() const { return type_ == kFatalFailure; } }; // 都支持流输出 TEST(CaseName, TestName) { // 产生一个断言成功的TestPartResult SUCCEED()<<"Something...";
// 产生一个非致命断言失败的TestPartResult ADD_FAILURE()<<"Something...";
// 产生一个致命断言失败的TestPartResult FAIL()<<"Something..."; } 事件监听: class EmptyTestEventListener : public TestEventListener { public: // Listener的被调用顺序一般会和下面顺序相差不多
// 测试程序启动时候调用,即RUN_ALL_TESTS()刚开始运行时候调用 virtual void OnTestProgramStart(const UnitTest& /*unit_test*/) {}
// 根据repeat次数多次调用,每次重复开始时调用,第二个参数传入第几次重复,从0开始。 virtual void OnTestIterationStart(const UnitTest& /*unit_test*/, int /*iteration*/) {}
// SetUp()调用开始前调用 virtual void OnEnvironmentsSetUpStart(const UnitTest& /*unit_test*/) {}
// SetUp()调用结束时调用 virtual void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) {}
// 测试用例开始时调用 virtual void OnTestCaseStart(const TestCase& /*test_case*/) {}
// 测试用例中的单个测试开始时调用 virtual void OnTestStart(const TestInfo& /*test_info*/) {}
// 每个断言结束后调用,TestPartResult参数传入断言的结果,详见上节 virtual void OnTestPartResult(const TestPartResult& /*test_part_result*/) {}
// 测试用例中的单个测试结束时调用 virtual void OnTestEnd(const TestInfo& /*test_info*/) {}
// 测试用例结束时调用 virtual void OnTestCaseEnd(const TestCase& /*test_case*/) {}
// TearDown()调用开始前调用 virtual void OnEnvironmentsTearDownStart(const UnitTest& /*unit_test*/) {}
// TearDown()调用结束后调用 virtual void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) {}
// 根据repeat次数多次调用,每次重复结束时调用,第二个参数传入第几次重复,从0开始。 virtual void OnTestIterationEnd(const UnitTest& /*unit_test*/, int /*iteration*/) {}
// 测试程序结束时候调用,即RUN_ALL_TESTS()刚结束运行时候调用 virtual void OnTestProgramEnd(const UnitTest& /*unit_test*/) {} }; 运行时可以通过–help, -h, -?或/?,来打印运行选项的帮助列表,所有的参数都是以两个-开头。 //--gest_print_time int main(int argc, char** argv) { // 关闭显示运行时间 // --gest_print_time ::testing::GTEST_FLAG(print_time) = false;
// --gest_list_tests ::testing::GTEST_FLAG(list_tests) = true;
// 这句代码将运行参数传入Google Test中 ::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS(); } 不进行测试只显示所有测试列表: TestCase1. TestName1 TestName2 TestCase2. TestName 对测试进行过滤,只运行指定的测试: * 代表任意数量任意字符 ? 代表任意单个字符 : 代表或者的关系 - 代表去除该匹配测试 . 代表左边是测试用例名,右边是具体测试名称 例如: · ./foo_test 无参数,运行所有测试 · ./foo_test –gtest_filter=* 运用*通配符,也是运行所有测试 · ./foo_test –gtest_filter=FooTest.* 只运行所有在FooTest测试用例中的测试 · ./foo_test –gtest_filter=*Null*:*Constructor* 只运行带有Null或者Constructor字符串的测试 · ./foo_test –gtest_filter=-*DeathTest.* 运行除了带有DeathTest字符串的测试用例中的所有测试 · ./foo_test –gtest_filter=FooTest.*-FooTest.Bar 运行在FooTest测试用例中除了FooTest.Bar的测试 通常运行测试的时候,测试系统会自动禁止DISABLED_*为测试用例或测试名称的测试运行。 // 默认是不运行的,加上运行选项则运行 TEST(FooTest, DISABLED_DoesAbc) { ... }
class DISABLED_BarTest : public ::testing::Test { ... }; TEST_F(DISABLED_BarTest, DoesXyz) { ... } --gtest_color=(yes|no|auto) Enable/disable colored output. The default is auto. --gtest_print_time=0 Don't print the elapsed time of each test. 对测试进行重复运行,会把当前测试序号传递给TestEventListeners的OnTestIterationStart和OnTestIterationEnd第二个参数,详见Event Listeners:
扰乱重复测试的顺序,将当前序号打乱传给OnTestIterationStart和OnTestIterationEnd,必须要和gtest_repeat选项同时使用。 给gtest_shuffle设置SEED,0-9999之间,0代表取当前系统时间为SEED。 支持xml格式的输出:
定向输出流到指定服务器: --gtest_stream_result_to=HOST:PORT
HOST服务器IP或域名,PORT服务器端口 --gtest_death_test_style=(fast|threadsafe) Set the default death test style. --gtest_break_on_failure Turn assertion failures into debugger break-points. 非常利于调试 --gtest_throw_on_failure Turn assertion failures into C++ exceptions. --gtest_catch_exceptions=0 Do not report exceptions as test failures. Instead, allow them to crash the program or throw a pop-up (on Windows). ValuesIn(const T (&array)[N]) //数组 ValuesIn(const Container& container) //STL容器 ValuesIn(Iterator begin, Iterator end) //迭代器 |