GoogleTestで型パラメータを使う
(久々に見てみたら人に見せる文章じゃないと感じたので修正。2019/02/12)
メモ。コードはこれ。
背景:テンプレートなテストしたい
やりたいテスト
- 任意の型Tの変数のやそれに対する関数のテスト
- 一応GoogleTestで可能
課題
- 一部のテストに問題があっても他のテストは走ってほしい
- 一旦は全部テスト走ってほしいけど、コンパイルエラーで止まることが多い
セットアップ(?)
- 必要な標準ライブラリ等をinclude
- テスト対象のheaderもinclude
(テスト対象と同じsolution内にテストを作ったなら../solution/テスト対象.hpp )
テスト定義
- ::testing::Testクラスを継承して、型パラメータを持つテストクラスを定義
- テストケースの宣言:TYPED_TEST_CASE_P( テストクラス )
- テストを書く:TYPED_TEST_P(テストクラス, テスト名){ /* テストを書く*/ }
- テストクラスとテストを登録:REGISTER_TYPED_TEST_CASE_P( テストクラス, テスト... )
//テストクラスの定義 templateclass IteratorTest:public ::testing::Test{ protected: constexpr static const auto size = 3; T a[size]{3,4,5}; public: IteratorTest() :a{} {} }; //テストケースの宣言 TYPED_TEST_CASE_P(IteratorTest); //テストその1 TYPED_TEST_P(IteratorTest, BeginEq) { EXPECT_EQ(zxc::st::begin(a), zxc::st::begin(a)); } /* テストを書いていく */ //テストクラスとテストを登録 REGISTER_TYPED_TEST_CASE_P( IteratorTest , BeginEq, EndEq, OldFor, RangeFor);
ここまでテスト定義。
ここからテストのインスタンス化
テストを走らせるためには型パラメータに実際に型を入れてINSTANTIATEする
- テストしたい型リストを生成(::testing::Types<テストしたい型を列挙...>)
- 型リストのエイリアス生成( using か typedef )
- テストのインスタンス生成
:INSTANTIATE_TYPED_TEST_CASE_P( インスタンス名, テストクラス, 型リスト)
//テストしたい型のリストを生成 と そのエイリアス生成 using DefTypes = ::testing::Types<int, const double, const int* >; //テストのインスタンス生成 INSTANTIATE_TYPED_TEST_CASE_P( Def, IteratorTest, DefTypes);
INSTANTIATE_TYPE_TEST_CASE_Pの第一引数Defはテストを識別する名前。下に貼った画像を見たらわかりやすいかもしれない。
ここで2のエイリアス生成は必須らしい。
INSTANTIATE_TYPED_TEST_CASE_Pの第3引数に直接入れるとコンパイルエラー
(ここでハマった)
他にも制約があって、クラス名やインスタンス名など、マクロのカッコ内に記述するテストケースの識別に使用しそうな名前にアンダーバー( _ )はあってはいけないらしい。
(マクロ内で名前は結合されるため、任意のマクロMにおいて
M( test_a, void )とM( test, a_void )が区別できないとかなんとか。
確かにそんなことが起きてしまうと、「片方のテストは通ったけれどどちらのテストケースが通ったのかは分からない」 なんて困ったことも起きるのかもしれない。)
usingでもtypdefでもどちらでもいいが、特に理由がないならusingで良いだろう。
古い方をわざわざ使う理由はあまりない。
GoogleTestで使用されているC++が確か古い規格であるためにサンプルではtypedefだったような気がする。
テスト結果
一応テスト結果の見方も載せておく。
今回は4つのテストが3つの型で走っているので全部で12 tests(一番下)。 最初の4つは型リストのindex=0であるint型についてのテスト。
テストの成否は色と文字(OKかFailed)でわかる。(今回全部OKにしたけど)
例えばインスタンスDefのIteratorTestのIndex=2(=int const*型の時)のOldForがどうか知ることができるのでエラー箇所の特定もできる。
別の方法でもテストできるらしい。 そちらはあまり調べていない。
マクロがたくさん出てくるのでテストコードのエラーが読みづらい。辛い。
入門ガイド — Google Test ドキュメント日本語訳
googletest/sample6_unittest.cc at master · google/googletest · GitHub