LoginSignup
5
1

More than 5 years have passed since last update.

GoogleTestがテストを登録する仕組みを調べてみた

Posted at

GoogleTestがどうやってテストを登録しているのか調べてみた.

TESTの展開

単純なテストは次のように書ける.

TEST(テストケース名, テスト名)
{
    // テスト内容
}

このテストは,マクロが展開されて次のようなコードになる.

class テストケース名_テスト名_Test : public ::testing::Test
{
public:
    テストケース名_テスト名_Test() {}
private:
    virtual void TestBody();
    static ::testing::TestInfo * const test_info_;
    テストケース名_テスト名_Test(テストケース名_テスト名_Test const &) = delete;
    void operator=(テストケース名_テスト名_Test const &) = delete;
};

::testing::TestInfo * const テストケース名_テスト名_Test::test_info_ = ::testing::internal::MaekAndRegisterTestInfo(
    "テストケース名",
    "テスト名",
    0,
    0,
    ::testing::internal::CodeLocation(ファイルパス, 行数),
    (::testing::internal::GetTestTypeId()),
    ::testing::Test::SetUpTestCase,
    ::testing::Test::TearDownTestCase,
    new ::testing::internal::TestFactoryImpl<テストケース名_テスト名_Test>
);

void テストケース名_テスト名_Test::TestBody()
{
    // テスト内容
}

まず,テストケースとテスト名から新しいクラスが作られ,test_info_というstaticメンバ変数が用意される.このtest_info_を初期化する際に,MakeAndRegisterTestInfo()を呼び出すことで,テストを登録しているようだ.

そして,テストの内容は,生成されたクラスのメンバ関数TestBody()の本体として扱われる.

MakeAndRegisterTestInfoの概要

MakeAndRegisterTestInfoについて,もう少し詳しく見てみる.宣言は次のようになっている.

TestInfo* MakeAndRegisterTestInfo(
    const char* test_case_name,
    const char* name,
    const char* type_param,
    const char* value_param,
    CodeLocation code_location,
    TypeId fixture_class_id,
    SetUpTestCaseFunc set_up_tc,
    TearDownTestCaseFunc tear_down_tc,
    TestFactoryBase* factory
)

仮引数の意味は次のようになっている.


test_case_name

テストケース名

test_name

テスト名

type_param

調査中

value_param

調査中

code_location

ファイルの位置とテスト開始行数

fixture_class_id

fixtureクラスのID.::testing::internal::GetTypeId<テストケース名>()で求める.

set_up_tc

テストケース開始前に呼び出される関数への関数ポインタ

tear_down_tc

テストケース終了後に呼び出される関数への関数ポインタ

factory

テストを生成するクラス

この関数は,実引数からTestInfoを生成し,::testing::UnitTestに登録する.実際には,::testing::internal::UnitTestImplに登録する.レポータによって切り替わるようだ.

この登録時に,テストケース別に登録するようになっており,初めて登録するテストケースの場合,自動的に新しいテストケース情報が登録されるようになっている.

テストの実行

テストの実行は,登録されたテストのTestBody()を実行しながら進んでいく.EXPECT_EQなどのアサート文を呼び出すと,
例外が有効であれば例外を,例外が無効であればWindowsの場合,Structured Exception Handling (SEH) を利用して,
問題を検出しているようだ.

まとめ

GoogleTestは,TESTマクロにより::testing::TestInfoのstatic変数を持ったクラスを生成し,その初期化を通してテストを登録している.

テストの本体は,::testing::Test::TestBody()の実装となり,実行時に呼び出される.

5
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
1