2020/10/03
GoogleTest の備忘録を記す。 ここを見たら GoogleTest を使える状態になれるような文書を目指す(が、参考ページの方が情報が確かそうなので目を通してほしいです!)。 適当にネット徘徊しながらまとめるので、マルチリンガルな文章になる予定。
GoogleTest とは
xUnit アーキテクチャに基づいたテストフレームワーク、JUnit や PyUnit の経験があればすぐに使い始められるとのこと(私は未経験)。
基本コンセプト
GoogleTest はマクロによる Assertion(条件の真偽を確認する文)から始まる。 Assertion の結果には以下3つがある。
- 成功
- 失敗
- 致命的な失敗
以下の場合、テスト自体が失敗となる。
- テストがクラッシュ
- Assertion が失敗
マクロによる Assertion とは、関数と似たようなものである。 クラス・関数のテストを行うには、それの動作を調べる Assertion を定義すると良い。
GoogleTest は、失敗を知らせるメッセージとともに、Assertion のソースファイルと該当行番号を出力する。 そこには、ユーザが定義した失敗メッセージを出力することも可能。
ここでは、Assertion によって致命的な失敗を定義することができる。致命的な失敗では、実行中の関数を中断する。そのため、メモリリークの原因となる可能性がある。
失敗しても多くの情報を得るために、基本的にはEXPECT_*
を使うことが望ましいが、失敗したら続ける意味が無い場合はASSERT_*
を使う。
Basic Assertions(基本的なアサーション)
致命的 assertion | 非致命的 assertion | 確認内容 |
---|---|---|
ASSERT_TRUE(条件); | EXPECT_TRUE(条件); | 条件が true |
ASSERT_FALSE(条件); | EXPECT_FALSE(条件); | 条件が false |
Binary Comparison(二値比較)
致命的 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
を用いる。
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
を加えると良いので覚えやすい。
Simple Tests
TEST()
マクロでテスト関数を定義して名前をつける。これは戻り値のない C++関数である。- 関数内で通常の C++のように自由にコードを書ける。その上で、上述した Assertion で値を検証する。
- 一つでも 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
と称して負値入力でバグを起こさないかテストしたい(雰囲気わかってきたぞ!)。
ステップアップ
ここまでで概要が掴めたと思うので、後は用途に合わせてサンプルや上級ガイドを参照すると良い(気が向いたら本ページも更新します)。