Googleテストフレームワーク(gtest)

コードのテストに関して疑問が生じたとき、boost :: testを使用することをためらいませんでした。 視野を広げるために、Google Test Frameworkを試しました。 boost :: testとは異なり、含まれるすべてのグッズに加えて、プロジェクトは活況を呈しています。 習得した知識を共有したいと思います。 興味のある人はみんな聞いて



キーコンセプト





Googleテストフレームワークの重要な概念は、アサートの概念です。 アサーションは、成功、致命的ではない失敗、および致命的な失敗を引き起こす可能性のある表現です。 重大な障害が発生するとテストが完了しますが、それ以外の場合はテストが続行されます。 テスト自体はステートメントのコレクションです。 さらに、テストはテストケースにグループ化できます。 オブジェクトの複雑なグループをさまざまなテストで使用する必要がある場合、フィクスチャを使用できます。 結合されたテストスイートはテストプログラムです。



アサーション



重大な障害を生成するステートメントは、falseの場合、ASSERT_、非重大-EXPECT_で始まります。 重大な障害が発生した場合、障害の原因となったステートメントが検出された関数から即座に返されることに注意してください。 このステートメントの後に何らかの種類のメモリクリーニングコードまたはその他の最終手順が続く場合、メモリリークが発生する可能性があります。



次のステートメントを使用できます(重要ではないステートメントは、ASSERT_ではなく、EXPECT_で始まります)。



シンプルなロジック







比較







文字列比較







例外チェック







述語チェック







浮動小数点の比較







チャレンジの失敗または成功







AssertionResultを返す独自の関数を作成できます



::testing::AssertionResult IsTrue(bool foo) { if (foo) return ::testing::AssertionSuccess(); else return ::testing::AssertionFailure() << foo << " is not true"; } TEST(MyFunCase, TestIsTrue) { EXPECT_TRUE(IsTrue(false)); }
      
      







:: testing :: StaticAssertTypeEq <T1、T2>()関数を使用してデータ型を制御できます。 タイプT1とT2が一致しない場合、コンパイルは失敗します。



ステートメントが偽の場合、ステートメントで使用されるデータが発行されます。 独自のコメントを設定することもできます:

 ASSERT_EQ(1, 0) << "1 is not equal 0";
      
      







拡張文字セット(wchar_t)は、文字列に関するコメントとアサーションの両方で使用できます。 この場合、出力はUTF-8エンコードになります。



テスト





テストを決定するには、TESTマクロを使用します。 ステートメントを使用できるvoid関数を定義します。 前述のように、重大な障害が発生すると、関数からすぐに戻ります。

 TEST(test_case_name, test_name) { ASSERT_EQ(1, 0) << "1 is not equal 0"; }
      
      







TESTは、テストを一意に識別する2つのパラメーター(テストスイートの名前とテストの名前)を受け入れます。 同じテストセット内で、テスト名が一致してはなりません。 名前がDISABLED_で始まる場合は、テスト(テストスイート)が一時的に未使用としてマークされていることを意味します。



テストの一部としてステートメントを使用できるだけでなく、任意の関数からステートメントを呼び出すこともできます。 唯一の制限があります-重大な障害を生成するステートメントは、非void関数から呼び出すことはできません。



備品





テストに関係するオブジェクトをテストごとに構成するのは困難です。 セットアッププロセスを一度設定すると、テストごとに自動的に実行できます。 そのような状況では、固定が使用されます。



コミットは:: testing :: Testから継承されたクラスであり、その内部ではテストに必要なすべてのオブジェクトが宣言されますが、コンストラクターまたはSetUp()関数ではセットアップされ、TearDown()関数でリソースが解放されます。 コミットを使用するテスト自体は、TEST_Fマクロを使用して宣言する必要があります。その最初のパラメーターは、テストスイートの名前ではなく、コミットの名前を指定する必要があります。



SetUp()を使用して構成されたテストごとに新しいコミットが作成され、テストが起動され、TearDown()を使用してリソースが解放され、コミットオブジェクトが削除されます。 したがって、各テストには、前のテストで「破損していない」固定の独自のコピーがあります。



 #include <gtest/gtest.h> #include <iostream> class Foo { public: Foo() : i(0) { std::cout << "CONSTRUCTED" << std::endl; } ~Foo() { std::cout << "DESTRUCTED" << std::endl; } int i; }; class TestFoo : public ::testing::Test { protected: void SetUp() { foo = new Foo; foo->i = 5; } void TearDown() { delete foo; } Foo *foo; }; TEST_F(TestFoo, test1) { ASSERT_EQ(foo->i, 5); foo->i = 10; } TEST_F(TestFoo, test2) { ASSERT_EQ(foo->i, 5); } int main(int argc, char *argv[]) { ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); }
      
      







場合によっては、テストオブジェクトの作成は非常に高価な操作であり、テストはオブジェクトに変更を加えません。 この場合、各テストのコミットを再作成することはできませんが、グローバルSetUp()およびTearDown()で分散コミットを使用します。 クラスに少なくとも1つの静的メンバーがある場合、コミットは自動的に分散されます。 静的関数SetUpTestCase()およびTearDownTestCase()は、それぞれオブジェクトを構成し、リソースを解放するために呼び出されます。 したがって、最初のテストの前のテストスイートはSetUpTestCase()を呼び出し、最後のTearDownTestCase()の後に呼び出します。



テストスイートだけでなく、テストプログラム全体でSetUp()およびTearDown()が必要な場合は、::: testing :: Environmentの継承クラスを作成し、SetUp()およびTearDown()をオーバーライドし、関数を使用して登録する必要がありますAddGlobalTestEnvironment。



テストを実行する





必要なすべてのテストを宣言したら、RUN_ALL_TESTS()関数を使用してテストを実行できます。 関数は1回しか呼び出すことができません。 一部の自動テストツールは、テストプログラムの結果を返すものによって決定するため、テストプログラムが関数RUN_ALL_TESTS()の結果を返すことが望ましいです。







RUN_ALL_TESTS()の前に呼び出されるInitGoogleTest(argc、argv)関数は、テストプログラムを、テスト結果を表示する単なる実行可能ファイル以上のものにします。 これは、動作を変更する入力パラメーターを受け入れる完全なアプリケーションです。 いつものように、-h、-helpオプションは、サポートされているすべてのオプションのリストを提供します。 それらのいくつかをリストします(完全なリストについては、ドキュメントを参照してください)。



パラメーターを常に使用する場合は、適切な環境変数を設定し、パラメーターなしで実行可能ファイルを実行できます。 たとえば、変数GTEST_ALSO_RUN_DISABLED_TESTSをゼロ以外の値に設定することは、-gtest_also_run_disabled_testsフラグを使用することと同等です。



結論の代わりに





この投稿では、Google Test Frameworkの主な機能について簡単に説明しました。 詳細については、 ドキュメントを参照してください。 そこから、プログラムのクラッシュ時に使用されるASSERT_DEATH、追加のログの維持、パラメーター化されたテスト、出力の設定、プライベートクラスメンバーのテストなどに関する情報を取得できます。



UPD: nikel ユーザーの公正な発言によると、フラグの使用に関する簡単な情報追加れました。

UPD 2: Habré(ネイティブタグソース)の変更後のマーキングの修正。



All Articles