これは何?
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::Matchers
と Catch
名前空間にあります。
文字列照合子
文字列照合子は、 StartsWith
、EndsWith
、Contains
、Equals
、および Matches
です。 最初の4つは結果とのリテラル(部分)文字列を照合しますが、Matches
はECMAScript 正規表現を用いて照合します。 Matches
は文字列全体と一致します。つまり、 "abc" は "abcd" と一致しませんが、 "abc.*" は一致します。
それぞれ提供されている std::string
照合子は、大文字小文字の区別を指定する、省略可能な第2引数を取ります(デフォルトでは、大文字と小文字が区別されます)。
ベクタ(vector)照合子
ベクタ照合子は Contains
、VectorContains
、Equals
です。 VectorContains
は照合するベクタ中の単一要素を探します。Contains
は、照合するベクタ中の、集合(set/vector)を探します。
浮動小数点照合子
浮動小数点照合子は WithinULP
と WithinAbs
です。 WithinAbs
は許容範囲内の浮動小数点値を受理します。WithinULP
は、2つの浮動小数点数のULP基準の比較を実行し、それらがある数のULPより小さい場合にそれらを受け取ります。
ULP基準の照合は、比較対象の値が同じ型であり、 WithinULP
がその引数の型を目標型とし
た時のみ意味を持ちます。 つまり、 withinULP(1.f, 1)
は float
の比較を期待しますが、 WithinULP(1., 1)
は double
の比較を期待します。
ユーザ定義照合子
Catch へ、独自照合子を与えることも、ユーザ定義型に対して照合させることも簡単にできます。
次の二つのことが必要です。
- 照合子クラスを
Catch::MatcherBase<T>
から派生させます。T
はテスト対象の型です。 コンストラクタは必要な引数(たとえば比較対象)を取得して格納します。また、match()
とdescribe()
の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