2014年10月14日火曜日

[gtest] OR 条件のアサーション

Google Group で OR 条件のアサーションはどう書くの?というトピックがあったので、紹介します。
Google C++ Testing Framework › Logical OR of EXPECT_*

AND は簡単だけど、OR は・・・
AND 条件は簡単に書けます。
TEST(Hoge, AndTest)
{
    ASSERT_NE(0, a);
    ASSERT_NE(4, a);
}

これは、a != 0 && a != 4 を意味します。

では、a == 0 || a == 4 のような条件を考えます。
TEST(Hoge, OrTest)
{
    EXPECT_EQ(0, a);
    EXPECT_EQ(4, a);
}
当然これはダメです。これでは AND になってしまします。
例えば、下記のように書けると良いのですが、残念ながらできません。
TEST(Hoge, OrTest)
{
    EXPECT_EQ(0, a) || EXPECT_EQ(4, a);
}

最も簡単な方法
Google Group でも紹介されていた最も簡単な方法です。

TEST(Hoge, OrTest)
{
    ASSERT_TRUE( a == 0 || a == 4 );
}
[----------] 1 test from Hoge
[ RUN      ] Hoge.OrTest
main.cpp(99): error: Value of: a == 0 || a == 4
  Actual: false
Expected: true
[  FAILED  ] Hoge.OrTest (4 ms)
[----------] 1 test from Hoge (6 ms total)

ただ、これでは失敗したときに a の値がなんだったのかわかりません。
なので、以下のようにして a の値を出力するようにします。

TEST(Hoge, OrTest)
{
    ASSERT_TRUE( a == 0 || a == 4 ) << "a = " << a;
}
出力はこのようになります。
[----------] 1 test from Hoge
[ RUN      ] Hoge.OrTest
main.cpp(99): error: Value of: a == 0 || a == 4
  Actual: false
Expected: true
a = 1
[  FAILED  ] Hoge.OrTest (4 ms)
[----------] 1 test from Hoge (6 ms total)

値の出力には SCOPED_TRACE を使う方法もあります。

TEST(Hoge, OrTest)
{
    SCOPED_TRACE( ::testing::Message() << a );
    ASSERT_TRUE( a == 0 || a == 4 );
}

SCOPED_TRACE は記述したスコープの間はメッセージが追記されます。なので、複数のアサーションを記述している場合は一箇所の修正で済むので楽です。
[----------] 1 test from Hoge
[ RUN      ] Hoge.OrTest
main.cpp(99): error: Value of: a == 0 || a == 4
  Actual: false
Expected: true
Google Test trace:
main.cpp(99): 1
[  FAILED  ] Hoge.OrTest (4 ms)
[----------] 1 test from Hoge (6 ms total)

Matcher を使う方法や他の方法もあると思いますが、Google Test のみの場合ではこの方法が一番だと思います。

0 件のコメント:

コメントを投稿