この記事では、GoogleTestでDeathテストの書き方を紹介します。
Deathテストとは、特定のコードがクラッシュすることを確認するためのテスト手法です。
主に意図的にプログラムが異常終了(assertやabort)するシナリオをテストするために使用されます。
Deathテストの構文
Google Testには、Deathテストを行うために使用できるいくつかのマクロがあります。
EXPECT_DEATH
指定されたコードブロックが異常終了することを期待し、その終了時のエラーメッセージが指定された正規表現に一致するかどうかをテストします。
EXPECT_DEATH(statement, regex);
- statement
-
異常終了することが期待されるコードブロック。
- regex
-
異常終了時に表示されるエラーメッセージに一致する正規表現。
ASSERT_DEATH
テストの途中で異常終了が発生した場合、そのテストを即座に中断します。
ASSERT_DEATH(statement, regex);
EXPECT_DEATH_IF_SUPPORTED
プラットフォームがDeathテストをサポートしている場合にのみEXPECT_DEATH
を実行します。サポートされていない場合は、テストをスキップします。
EXPECT_DEATH_IF_SUPPORTED(statement, regex);
ASSERT_DEATH_IF_SUPPORTED
EXPECT_DEATH_IF_SUPPORTED
と同様に、Deathテストをサポートしている場合のみ実行され、サポートされていない場合はテストをスキップします。
ASSERT_DEATH_IF_SUPPORTED(statement, regex);
ASSERT_EXIT
指定した関数が指定された終了ステータスコードで終了するかどうかを検証します。異常終了ではなく、特定の終了コードを確認したい場合に使用します。
ASSERT_EXIT(statement, predicate, regex);
- statement
-
異常終了することが期待されるコードブロック。
- predicate
-
終了コードを評価するラムダ関数または関数。
- regex
-
異常終了時に表示されるエラーメッセージに一致する正規表現。
EXPECT_EXIT
指定された関数が指定された終了ステータスコードで終了するかどうかを検証するためのマクロです。テストが失敗しても続行できる場合に使用します。
EXPECT_EXIT(statement, predicate, regex);
サンプルコード
以下は、簡単なソースコードとそれに対するDeathテストコードの例です。
テスト対象コード
// sample.cpp
#include <iostream>
#include <stdexcept>
void CheckPositive(int number) {
if (number <= 0) {
std::cerr << "Number must be positive!" << std::endl;
std::abort(); // 異常終了
}
std::cout << "Number is positive." << std::endl;
}
void CheckNotNull(void* ptr) {
if (ptr == nullptr) {
std::cerr << "Pointer is null!" << std::endl;
std::abort(); // 異常終了
}
std::cout << "Pointer is valid." << std::endl;
}
テストコード
// sample_test.cpp
#include <gtest/gtest.h>
#include "sample.cpp" // テスト対象のソースコードをインクルード
// `CheckPositive` 関数が0または負の値で呼ばれたときに異常終了することを確認
TEST(DeathTest, CheckPositiveDeath) {
EXPECT_DEATH(CheckPositive(0), "Number must be positive!");
EXPECT_DEATH(CheckPositive(-10), "Number must be positive!");
}
// `CheckNotNull` 関数がnullptrで呼ばれたときに異常終了することを確認
TEST(DeathTest, CheckNotNullDeath) {
EXPECT_DEATH(CheckNotNull(nullptr), "Pointer is null!");
}
// 正常なケースでは異常終了しないことを確認
TEST(DeathTest, CheckPositiveSuccess) {
EXPECT_NO_FATAL_FAILURE(CheckPositive(10));
}
TEST(DeathTest, CheckNotNullSuccess) {
int value = 42;
EXPECT_NO_FATAL_FAILURE(CheckNotNull(&value));
}
int main(int argc, char **argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
実行結果
[==========] Running 4 tests from 1 test suite.
[----------] Global test environment set-up.
[----------] 4 tests from DeathTest
[ RUN ] DeathTest.CheckPositiveDeath
[ OK ] DeathTest.CheckPositiveDeath (2 ms)
[ RUN ] DeathTest.CheckNotNullDeath
[ OK ] DeathTest.CheckNotNullDeath (2 ms)
[ RUN ] DeathTest.CheckPositiveSuccess
Number is positive.
[ OK ] DeathTest.CheckPositiveSuccess (0 ms)
[ RUN ] DeathTest.CheckNotNullSuccess
Pointer is valid.
[ OK ] DeathTest.CheckNotNullSuccess (0 ms)
[----------] 4 tests from DeathTest (4 ms total)
[----------] Global test environment tear-down
[==========] 4 tests from 1 test suite ran. (4 ms total)
[ PASSED ] 4 tests.