googletestでは、テストケースはこう書くわけ。
#include <gtest/gtest.h>
TEST(SampleTestCase, TestFunc) {
EXPECT_TRUE(true);
}
C++な割にはスマート。で、なんで、こんなことができるのか。その仕組みを追ってみた。まずは、TEST()マクロ。
include/gtest/gtest.h:
#define TEST(test_case_name, test_name) \
GTEST_TEST_(test_case_name, test_name, \
::testing::Test,\
::testing::internal::GetTestTypeId())
ほむ。次はGTEST_TEST_()マクロ。
include/gtest/internal/gtest-internal.h(抜粋):
#define GTEST_TEST_(test_case_name, test_name, parent_class, parent_id)\
class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) : public parent_class {\
public:\
GTEST_TEST_CLASS_NAME_(test_case_name, test_name)() {}\
private:\
virtual void TestBody();\
};\
\
void GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::TestBody()
ほむほむ。GTEST_TEST_CLASS_NAME_()マクロは、test_case_nameとtest_nameを繋げて重複しないクラス名を生成する。上の例だと SampleTestCase_TestFunc_Test となる。最後の行は TestBody() のシグニチャだけ置いて、マクロに続くブロックが TestBody() の実装となるようになっているわけだ。
ちなみに、親クラスとなる ::testing::Test は include/gtest/gtest.h で定義されている。
include/gtest/gtest.h(抜粋):
class Test {
protected:
virtual void SetUp();
virtual void TearDown();
private:
virtual void TestBody() = 0;
};
ほむほむほむ。予想どおり。
まとめ
最後に始めに出した例と、展開されたあとのイメージを載せておく。
展開前:
TEST(SampleTestCase, TestFunc) {
EXPECT_TRUE(true);
}
展開後:
class SampleTestCase_TestFunc_Test : public ::testing::Test {
public:
SampleTestCase_TestFunc_Test() {}
private:
virtual void TestBody();
};
void SampleTestCase_TestFunc_Test::TestBody() {
EXPECT_TRUE(true);
}
なるほどねぇ。