ys memos

Blog

GoogleTestの備忘録


googletest

2020/10/03

GoogleTest の備忘録を記す。 ここを見たら GoogleTest を使える状態になれるような文書を目指す(が、参考ページの方が情報が確かそうなので目を通してほしいです!)。 適当にネット徘徊しながらまとめるので、マルチリンガルな文章になる予定。


xUnit アーキテクチャに基づいたテストフレームワーク、JUnit や PyUnit の経験があればすぐに使い始められるとのこと(私は未経験)。


GoogleTest はマクロによる Assertion(条件の真偽を確認する文)から始まる。 Assertion の結果には以下3つがある。

  • 成功
  • 失敗
  • 致命的な失敗

以下の場合、テスト自体が失敗となる。

  • テストがクラッシュ
  • Assertion が失敗

マクロによる Assertion とは、関数と似たようなものである。 クラス・関数のテストを行うには、それの動作を調べる Assertion を定義すると良い。

GoogleTest は、失敗を知らせるメッセージとともに、Assertion のソースファイルと該当行番号を出力する。 そこには、ユーザが定義した失敗メッセージを出力することも可能。

ここでは、Assertion によって致命的な失敗を定義することができる。致命的な失敗では、実行中の関数を中断する。そのため、メモリリークの原因となる可能性がある。

失敗しても多くの情報を得るために、基本的にはEXPECT_*を使うことが望ましいが、失敗したら続ける意味が無い場合はASSERT_*を使う。


致命的 assertion非致命的 assertion確認内容
ASSERT_TRUE(条件);EXPECT_TRUE(条件);条件が true
ASSERT_FALSE(条件);EXPECT_FALSE(条件);条件が false

致命的 assertion非致命的 assertion確認内容
ASSERT_EQ(値 1, 値 2);EXPECT_EQ(値 1, 値 2);値 1 == 値 2
ASSERT_NE(値 1, 値 2);EXPECT_NE(値 1, 値 2);値 1 != 値 2
ASSERT_LT(値 1, 値 2);EXPECT_LT(値 1, 値 2);値 1 < 値 2
ASSERT_LE(値 1, 値 2);EXPECT_LE(値 1, 値 2);値 1 <= 値 2
ASSERT_GT(値 1, 値 2);EXPECT_GT(値 1, 値 2);値 1 > 値 2
ASSERT_GE(値 1, 値 2);EXPECT_GE(値 1, 値 2);値 1 >= 値 2

TeX のショートカットと類似しているので、若干覚えやすいという印象。

ASSERT_EA()では、「正解値」「算出値」の順で引数にする。

二値は比較可能である必要がある(満たしていないと CE となる)。特に、ユーザ定義型であっても比較演算子が定義されていれば使うことが出来るが、Basic Assertionを使うほうが望ましい。

引数は一度だけ評価される。また、評価順序は未定義のため、どちらが先に呼ばれるかに依存するコードは禁止。

引数がポインタの場合は、ポインタが等しいかを評価する。つまり、C 文字列(char*, wchar_t*等)を引数にするとアドレスが等しいかを比較してしまうため、以下で記述するString Comparisonを用いる。


注意する必要があるのが、C 文字列(char等)を比較するためのものである点。

致命的 assertion非致命的 assertion確認内容
ASSERT_STREQ(文字列 1,文字列 2);EXPECT_STREQ(文字列 1,文字列 2);C 文字列 1 == C 文字列 2
ASSERT_STRNE(文字列 1,文字列 2);EXPECT_STRNE(文字列 1,文字列 2);C 文字列 1 != C 文字列 2
ASSERT_STRCASEEQ(文字列 1,文字列 2);EXPECT_STRCASEEQ(文字列 1,文字列 2);大文字小文字を無視した時、C 文字列 1 == C 文字列 2
ASSERT_STRCASENE(文字列 1,文字列 2);EXPECT_STRCASENE(文字列 1,文字列 2);大文字小文字を無視した時、C 文字列 1 != C 文字列 2

二値比較にSTR,STRCASEを加えると良いので覚えやすい。


  1. TEST()マクロでテスト関数を定義して名前をつける。これは戻り値のない C++関数である。
  2. 関数内で通常の C++のように自由にコードを書ける。その上で、上述した Assertion で値を検証する。
  3. 一つでも Assertion が失敗すればテスト全体が失敗した扱いとなる。

階乗を返す以下の関数があるとする。

int Factorial(int n);  // Returns the factorial of n

以下のようにテストを定義することが出来る(公式 Githubから引用)。

TEST(FactorialTest, HandleZeroInput) {
  EXPECT_EQ(Factorial(0), 1);
}

TEST(FactorialTest, HandlesPositiveInput) {
  EXPECT_EQ(Factorial(1), 1);
  EXPECT_EQ(Factorial(2), 2);
  EXPECT_EQ(Factorial(3), 6);
  EXPECT_EQ(Factorial(8), 40320);
}

ここでは、HandleZeroInputにおいて境界条件の0入力を確認し、HandlesPositiveInputにおいて正値入力に対する結果をテストしている。

私がここに新たにテストを追加するとしたら、HandlesNegativeInputと称して負値入力でバグを起こさないかテストしたい(雰囲気わかってきたぞ!)。


ここまでで概要が掴めたと思うので、後は用途に合わせてサンプル上級ガイドを参照すると良い(気が向いたら本ページも更新します)。


関連タグを探す