ベクターをboost.testと比較する方法は?
-
10-10-2019 - |
質問
ブーストテストを使用して、いくつかのC ++コードをユニットテストしています。
予想される結果と比較する必要がある値のベクトルがありますが、ループ内の値を手動で確認したくありません。
BOOST_REQUIRE_EQUAL(values.size(), expected.size());
for( int i = 0; i < size; ++i )
{
BOOST_CHECK_EQUAL(values[i], expected[i]);
}
主な問題は、ループチェックがインデックスを印刷しないため、不一致を見つけるために検索が必要であることです。
使用できます std::equal
また std::mismatch
2つのベクトルでは、それには多くのボイラープレートも必要です。
これを行うためのよりクリーンな方法はありますか?
解決
使用する BOOST_CHECK_EQUAL_COLLECTIONS
. 。それはマクロです test_tools.hpp
2組の反復剤が必要です。
BOOST_CHECK_EQUAL_COLLECTIONS(values.begin(), values.end(),
expected.begin(), expected.end());
インデックスと不一致の値を報告します。サイズが一致しない場合、それも同様に報告します(そして、ベクトルの端から走るだけではありません)。
使用したい場合は注意してください BOOST_CHECK_EQUAL
また BOOST_CHECK_EQUAL_COLLECTIONS
POD以外のタイプを使用すると、実装する必要があります
bool YourType::operator!=(const YourType &rhs) // or OtherType
std::ostream &operator<<(std::ostream &os, const YourType &yt)
それぞれ比較とロギング用。
繰り返しの順序が渡されました BOOST_CHECK_EQUAL_COLLECTIONS
どちらがRHSとLHSであるかを決定します !=
比較 - 最初のイテレーター範囲は、比較のLHSです。
他のヒント
ただし、少しトピックで、時々、フローティングポイント数のコレクションを使用して比較する必要がある場合がある場合 許容範囲との比較 その後、このスニペットは使用するかもしれません:
// Have to make it a macro so that it reports exact line numbers when checks fail.
#define CHECK_CLOSE_COLLECTION(aa, bb, tolerance) { \
using std::distance; \
using std::begin; \
using std::end; \
auto a = begin(aa), ae = end(aa); \
auto b = begin(bb); \
BOOST_REQUIRE_EQUAL(distance(a, ae), distance(b, end(bb))); \
for(; a != ae; ++a, ++b) { \
BOOST_CHECK_CLOSE(*a, *b, tolerance); \
} \
}
これは、不一致の要素の配列インデックスを印刷するものではありませんが、不一致の値を高い精度で印刷するため、多くの場合簡単に見つけることができます。
使用例:
auto mctr = pad.mctr();
std::cout << "mctr: " << io::as_array(mctr) << '\n';
auto expected_mctr{122.78731602430344,-13.562000155448914};
CHECK_CLOSE_COLLECTION(mctr, expected_mctr, 0.001);
どうですか boost_check_equal_collections?
BOOST_AUTO_TEST_CASE( test )
{
int col1 [] = { 1, 2, 3, 4, 5, 6, 7 };
int col2 [] = { 1, 2, 4, 4, 5, 7, 7 };
BOOST_CHECK_EQUAL_COLLECTIONS( col1, col1+7, col2, col2+7 );
}
例
1つのテストケースを実行しています...
test.cpp(11):「test」のエラー:{col1、col1+7} == {col2、col2+7}を確認しました。
位置2:3!= 4の不一致
ポジション5:6!= 7の不一致
* 1テストスイートで検出された障害「例」
ブースト1.59以来、比較する方がはるかに簡単です std::vector
インスタンス。見る このドキュメント バージョン1.63の場合(この点で1.59にほぼ等しい)。
たとえば、宣言した場合 std::vector<int> a, b;
あなたは書ける
BOOST_TEST(a == b);
非常に基本的な比較を得るため。これの欠点は、障害の場合にブーストがあなたにそれだけを伝えるということです a
と b
同じではありません。しかし、エレガントな方法で可能な要素と比較することで、より多くの情報を得ることができます
BOOST_TEST(a == b, boost::test_tools::per_element() );
または、辞書誌の比較が必要な場合は
BOOST_TEST(a <= b, boost::test_tools::lexicographic() );
使用できます BOOST_REQUIRE_EQUAL_COLLECTIONS
と std::vector<T>
, 、しかし、あなたはboost.testを教える必要があります。 std::vector
ベクトルのベクトルまたは値がベクトルであるマップがある場合。マップがある場合は、boost.testを印刷する方法を教える必要があります std::pair
. 。の定義を変更できないためです std::vector
また std::pair
, 、あなたが定義するストリーム挿入演算子がboost.testによって使用されるようにこれを行う必要があります。 std::vector
. 。また、この手法は、Boost.testを幸せにするためだけに、テスト中のシステムにストリーム挿入演算子を追加したくない場合に役立ちます。
これが任意のレシピです std::vector
:
namespace boost
{
// teach Boost.Test how to print std::vector
template <typename T>
inline wrap_stringstream&
operator<<(wrap_stringstream& wrapped, std::vector<T> const& item)
{
wrapped << '[';
bool first = true;
for (auto const& element : item) {
wrapped << (!first ? "," : "") << element;
first = false;
}
return wrapped << ']';
}
}
これにより、ベクトルが形成されます [e1,e2,e3,...,eN]
でベクトルの場合 N
要素と、たとえば、ベクトルの要素もベクトルである場合、任意の数のネストされたベクトルに対して機能します。
これが同様のレシピです std::pair
:
namespace boost
{
// teach Boost.Test how to print std::pair
template <typename K, typename V>
inline wrap_stringstream&
operator<<(wrap_stringstream& wrapped, std::pair<const K, V> const& item)
{
return wrapped << '<' << item.first << ',' << item.second << '>';
}
}
BOOST_REQUIRE_EQUAL_COLLECTIONS
2つのコレクションが同じサイズであると仮定して、不一致のアイテムのインデックスと2つのコレクションの内容を教えてくれます。サイズが異なる場合、それはミスマッチと見なされ、サイズが異なると見なされます。