GoogleTestで型パラメータを使う


(久々に見てみたら人に見せる文章じゃないと感じたので修正。2019/02/12)


メモ。コードはこれ。

github.com


背景:テンプレートなテストしたい

  •  Microsoft Visual community でC++のテストにGoogleTestが使える
  •  他にはBOOST_TESTなども使える
  •  とりあえずGoogleTestやってみる


やりたいテスト

  • 任意の型Tの変数のやそれに対する関数のテスト
  • 一応GoogleTestで可能


課題

  • 一部のテストに問題があっても他のテストは走ってほしい
  • 一旦は全部テスト走ってほしいけど、コンパイルエラーで止まることが多い


セットアップ(?)

  1. 必要な標準ライブラリ等をinclude
  2. テスト対象のheaderもinclude
    (テスト対象と同じsolution内にテストを作ったなら../solution/テスト対象.hpp )


テスト定義

  1. ::testing::Testクラスを継承して、型パラメータを持つテストクラスを定義
  2. テストケースの宣言:TYPED_TEST_CASE_P( テストクラス )
  3. テストを書く:TYPED_TEST_P(テストクラス, テスト名){ /* テストを書く*/ }
  4. テストクラスとテストを登録:REGISTER_TYPED_TEST_CASE_P( テストクラス, テスト... )
//テストクラスの定義
template
class 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する

  1. テストしたい型リストを生成(::testing::Types<テストしたい型を列挙...>)
  2. 型リストのエイリアス生成( using か typedef )
  3. テストのインスタンス生成
    :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だったような気がする。



テスト結果

f:id:zxc_programming:20190212183534p:plain

テスト結果


 一応テスト結果の見方も載せておく。
今回は4つのテストが3つの型で走っているので全部で12 tests(一番下)。 最初の4つは型リストのindex=0であるint型についてのテスト。
テストの成否は色と文字(OKFailed)でわかる。(今回全部OKにしたけど)
 例えばインスタンスDefのIteratorTestのIndex=2(=int const*型の時)のOldForがどうか知ることができるのでエラー箇所の特定もできる。


別の方法でもテストできるらしい。 そちらはあまり調べていない。


マクロがたくさん出てくるのでテストコードのエラーが読みづらい。辛い。

Google Testの使い方 - Qiita

入門ガイド — Google Test ドキュメント日本語訳

googletest/sample6_unittest.cc at master · google/googletest · GitHub