2012年3月2日金曜日

Google Test を使ってみる - その5(関数内の失敗)

まずは、下記のコードをご覧下さい。
void SubTest(int** pp)
{
    *pp = NULL;
    ASSERT_TRUE( NULL != *pp );
}

TEST(Sample, Test)
{
    int* p=NULL;

    SubTest(&p);

    ASSERT_TRUE( NULL != p );
}
さて、このテストは失敗します。失敗しますが、あなたはどのような結果を望みますか?

[----------] 1 test from Sample
[ RUN      ] Sample.Test
main.cpp(4): error: Value of: NULL != *pp
  Actual: false
Expected: true
main.cpp(11): error: Value of: NULL != p
  Actual: false
Expected: true
[  FAILED  ] Sample.Test (1 ms)
[----------] 1 test from Sample (2 ms total)

実際に実行してみると、このような結果になります。
期待通りでしたか?


期待通り?いや、期待通りではない?ですよね??
そうなんです。
SubTest 関数で ASSERT_TRUE が失敗しても Test は続行されてしまうのです。
実は、ASSERT_* マクロはテストを中断するために return するだけなのです。

では、どのようにしてテストを中断したらよいのでしょう。

例外を使う
幸いなことに Google Test には例外を使うオプションが用意されています。
--gtest_throw_on_failure を使うと、失敗時に例外を投げるようになります。

結果がこちら。
[ RUN      ] Sample.Test
main.cpp(7): error: Value of: NULL != *pp
  Actual: false
Expected: true
続行するには何かキーを押してください . . .

テストが中断するようになりました。が、テスト全体が中断するようになってしまいました。
これは、意図している結果と少し違います。

ここでは、SubTest で失敗が発生したら Sample.Test のみを中断させたいのです。

ASSERT_NO_FATAL_FAILURE を使う
ASSERT_NO_FATAL_FAILURE という、このためだけにあると言っても過言ではないマクロがあります。
ASSERT_NO_FATAL_FAILURE(statement) マクロでは、 statement で失敗が発生した場合に失敗します。

では、早速組み込んでみましょう。

TEST(Sample, Test)
{
    int* p=NULL;

    ASSERT_NO_FATAL_FAILURE( SubTest(&p) );

    ASSERT_TRUE( NULL != p );
}

SubTest の呼び出しを、ASSERT_NO_FATAL_FAILURE で囲うだけです。
続いて、出力結果です。

[----------] 1 test from Sample
[ RUN      ] Sample.Test
main.cpp(4): error: Value of: NULL != *pp
  Actual: false
Expected: true
main.cpp(11): error: Expected: SubTest(&p) doesn't generate new fatal failures in the current thread.
  Actual: it does.
[  FAILED  ] Sample.Test (16 ms)
[----------] 1 test from Sample (16 ms total)

期待通り、SubTest 内部で発生した失敗を検知し Sample.Test が中断するようになりました!
これで、テストの記述の仕方の幅が広がりましたね!

今回はここまで。

※ Google Test 関係の記事一覧はこちら

0 件のコメント:

コメントを投稿