エンジニアのソフトウェア的愛情

または私は如何にして心配するのを止めてプログラムを・愛する・ようになったか

その2:アサーションの解説(1)

二種類のアサーション

googletestのアサーションには大きく二種類のアサーションマクロが用意されています。
一つは評価が失敗した時点でテストを終了する、名前がASSERT_で始まるマクロ。もう一つは評価が失敗してもテストを継続する、名前がEXPECT_で始まるマクロです。


名前がASSERT_で始まるマクロの場合、例えば次のようなコードでは(1)で評価が失敗した場合(2)は実行されません。

ASSERT_TRUE(a); // (1)
ASSERT_TRUE(b); // (2)

評価が失敗したときに実行されないのは以降のTESTマクロの内部のみで、テストケース全体やテストスイート全体が実行されなくなるわけではありません。


一方、名前がEXPECT_で始まるマクロの場合、次のようなコードで(3)の評価が失敗しても(4)も実行されます。

EXPECT_TRUE(a); // (3)
EXPECT_TRUE(b); // (4)

アサーションマクロの一覧

基本になるAssertion
Fatal assertion Nonfatal assertion Verifies
ASSERT_TRUE(condition) EXPECT_TRUE(condition) condition is true
ASSERT_FALSE(condition) EXPECT_FALSE(condition) condition is false

式の真偽を評価するマクロです。
ASSERT_TRUEEXPECT_TRUEは式が真のとき、ASSERT_FALSEEXPECT_FALSEは式が偽のときに評価がパスします。

TEST(ListTest, Test1)
{
    std::list<int> l;
    ASSERT_TRUE(l.empty());
    l.push_back(1);
    ASSERT_FALSE(l.empty());
}
ふたつの値を比較するアサーション
Fatal assertion Nonfatal assertion Verifies
ASSERT_EQ(expected, actual) EXPECT_EQ(expected, actual) expected == actual
ASSERT_NE(val1, val2) EXPECT_NE(val1, val2) val1 != val2
ASSERT_LT(val1, val2) EXPECT_LT(val1, val2) val1 < val2
ASSERT_LE(val1, val2) EXPECT_LE(val1, val2) val1 <= val2
ASSERT_GT(val1, val2) EXPECT_GT(val1, val2) val1 > val2
ASSERT_GE(val1, val2) EXPECT_GE(val1, val2) val1 >= val2

ふたつの値を比較するマクロです。
評価する値は、マクロに対応する演算子(たとえば*_EQならoperator ==)が定義されていなければなりません。
加えてストリームへ出力するための挿入演算子(operator <<)が定義されている必要があります。

struct Point
{
    int x;
    int y;
};

bool operator < (const Point& lhs, const Point& rhs)
{
    return ((lhs.x * lhs.x) + (lhs.y * lhs.y)) < ((rhs.x * rhs.x) + (rhs.y * rhs.y));
}

bool operator >= (const Point& lhs, const Point& rhs)
{
    return rhs < lhs;
}

std::ostream& operator << (std::ostream& out, const Point& point)
{
    return out << "(" << point.x << ", " << point.y << ")";
}

TEST(ListTest, Test1)
{
    Point p1 = { 1, 1 };
    Point p2 = { 2, 2 };
    ASSERT_LT(p1, p2); // operator < を使って値を評価する。
    ASSERT_GE(p1, p2); // operator >= を使って値を評価する。失敗したときは、operator << を使って値が出力される。
}

これらのマクロにポインタが与えられた場合、ポインタの値どうしが比較されます。C言語形式の文字列を比較する場合は後述のASSERT_STR*を使用してください。

C言語形式の文字列を比較するアサーション
Fatal assertion Nonfatal assertion Verifies
ASSERT_STREQ(expected_str, actual_str) EXPECT_STREQ(expected_str, actual_str) the two C strings have the same content
ASSERT_STRNE(str1, str2) EXPECT_STRNE(str1, str2) the two C strings have different content
ASSERT_STRCASEEQ(expected_str, actual_str) EXPECT_STRCASEEQ(expected_str, actual_str) the two C strings have the same content, ignoring case
ASSERT_STRCASENE(str1, str2) EXPECT_STRCASENE(str1, str2) the two C strings have different content, ignoring case

C言語形式の文字列を比較するマクロです。
名前にCASEがついたマクロは文字列中の文字の大文字小文字を無視して比較します。
NULLと空文字列("")は異なるものとして評価します。

TEST(StrTest, Test1)
{
    const char  s1[] = "hoge";
    const char  s2[] = "HOGE";

    ASSERT_STRCASEEQ(s1, s2); // 成功
}

TEST(StrTest, Test2)
{
    const char  s1[] = "hoge";
    const char  s2[] = "HOGE";

    ASSERT_STREQ(s1, s2); // 失敗
}

TEST(StrTest, Test3)
{
    const char  s1[] = "";
    const char* s2   = 0;

    ASSERT_STREQ(s1, s2); // 失敗
}

std::stringの値を比較する場合は、ASSERT_EQASSERT_NEなどを使います。