LoginSignup
4
0

More than 5 years have passed since last update.

Catch2 Matchers

Last updated at Posted at 2018-01-05

これは何?

https://github.com/catchorg/Catch2/blob/master/docs/matchers.md commit/b0857e846fc82c2d26b57170f6d5d0f5abb27fa5 の和訳
ほとんど google 翻訳とも言う。
Matcher を "照合子" と訳しています。演算子的な気持ちです。カタカナで書くと頭に入ってこないので、できるだけ日本語にしたい気持ち。変な訳なところはご容赦ください。

照合子(Matchers)

照合子は、容易に拡張可能で構成可能なアサーションを行うための代替手段です。
これにより、より複雑な型(コレクションなど)や独自のカスタム型での使用に適しています。
照合子 は Hamcrest のフレームワークの一部として生まれました。

In use

照合子は REQUIRE_THAT または CHECK_THAT マクロで導入され、2つの引数をとります。
最初の引数は、テスト対象のオブジェクト(オブジェクトまたは値)です。 2番目の部分は一致で、1つの照合子または1つ以上の照合子を &&|| または ! 演算子で連結させて構成します。

たとえば、文字列が特定の部分文字列で終わることをアサートするには、次のようにします。

using Catch::Matchers::EndsWith; // または Catch::EndsWith
std::string str = getStringFromSomewhere();
REQUIRE_THAT( str, EndsWith( "as a service" ) ); 

照合子オブジェクトは複数の引数を取ることができ、より細かい調整ができます。
たとえば、組み込み済み文字列照合子は、比較が大文字と小文字を区別するかどうかを指定する2番目の引数をとります。

REQUIRE_THAT( str, EndsWith( "as a service", Catch::CaseSensitive::No ) ); 

また、照合子は組み合わせられます。

REQUIRE_THAT( str, 
    EndsWith( "as a service" ) || 
    (StartsWith( "Big data" ) && !Contains( "web scale" ) ) ); 

組み込み済み照合子

Catch は現在、いくつかの照合子を提供しています。それらは Catch::MatchersCatch 名前空間にあります。

文字列照合子

文字列照合子は、 StartsWithEndsWithContainsEquals、および Matches です。 最初の4つは結果とのリテラル(部分)文字列を照合しますが、MatchesはECMAScript 正規表現を用いて照合します。 Matches は文字列全体と一致します。つまり、 "abc" は "abcd" と一致しませんが、 "abc.*" は一致します。

それぞれ提供されている std::string 照合子は、大文字小文字の区別を指定する、省略可能な第2引数を取ります(デフォルトでは、大文字と小文字が区別されます)。

ベクタ(vector)照合子

ベクタ照合子は ContainsVectorContainsEquals です。 VectorContains は照合するベクタ中の単一要素を探します。Contains は、照合するベクタ中の、集合(set/vector)を探します。

浮動小数点照合子

浮動小数点照合子は WithinULPWithinAbs です。 WithinAbs は許容範囲内の浮動小数点値を受理します。WithinULPは、2つの浮動小数点数のULP基準の比較を実行し、それらがある数のULPより小さい場合にそれらを受け取ります。

ULP基準の照合は、比較対象の値が同じ型であり、 WithinULP がその引数の型を目標型とし
た時のみ意味を持ちます。 つまり、 withinULP(1.f, 1)float の比較を期待しますが、 WithinULP(1., 1)double の比較を期待します。

ユーザ定義照合子

Catch へ、独自照合子を与えることも、ユーザ定義型に対して照合させることも簡単にできます。

次の二つのことが必要です。

  1. 照合子クラスを Catch::MatcherBase<T> から派生させます。T はテスト対象の型です。 コンストラクタは必要な引数(たとえば比較対象)を取得して格納します。また、 match()describe() の2つのメソッドをオーバーライドする必要があります。
  2. 単純なビルダ関数。これは実際のテストコードから呼ばれ、オーバーロードを許容します。

整数が指定範囲内にあるか、アサートする例を以下に示します
(例を簡潔にするため、すべてインラインであることに注意してください)。

// 照合子クラス
class IntRange : public Catch::MatcherBase<int> {
    int m_begin, m_end;
public:
    IntRange( int begin, int end ) : m_begin( begin ), m_end( end ) {}

    // この照合子で検査する
    virtual bool match( int const& i ) const override {
        return i >= m_begin && i <= m_end;
    }

    // この照合子の検査内容の説明文を生成します。与えられるデータを
    // 含めなければなりません (この場合は begin/ end)。 また、
    // 事実を述べるような記述にしてください (出力では、
    // 被検査値の前に置かれます).
    virtual std::string describe() const {
        std::ostringstream ss;
        ss << "is between " << m_begin << " and " << m_end;
        return ss.str();
    }
};

// ビルダ関数
inline IntRange IsBetween( int begin, int end ) {
    return IntRange( begin, end );
}

// ...

// 使い方
TEST_CASE("Integers are within a range")
{
    CHECK_THAT( 3, IsBetween( 1, 10 ) );
    CHECK_THAT( 100, IsBetween( 1, 10 ) );
}

このテストを実行すると、コンソールに次のように表示されます。

/**/TestFile.cpp:123: FAILED:
  CHECK_THAT( 100, IsBetween( 1, 10 ) )
with expansion:
  100 is between 1 and 10

4
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
0