#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); }なるほどねぇ。