28

BoostTestを使用してC++コードの単体テストを行っています。

期待される結果と比較する必要のある値のベクトルがありますが、ループ内の値を手動でチェックしたくありません。

BOOST_REQUIRE_EQUAL(values.size(), expected.size());

for( int i = 0; i < size; ++i )
{
    BOOST_CHECK_EQUAL(values[i], expected[i]);
}

主な問題は、ループチェックでインデックスが出力されないため、不一致を見つけるために検索が必要になることです。

std::equalまたは2つのベクトルを使用できますstd::mismatchが、それには多くの定型文も必要になります。

これを行うためのよりクリーンな方法はありますか?

4

5 に答える 5

36

を使用しBOOST_CHECK_EQUAL_COLLECTIONSます。test_tools.hppこれは、2組のイテレータを使用するマクロです。

BOOST_CHECK_EQUAL_COLLECTIONS(values.begin(), values.end(), 
                              expected.begin(), expected.end());

不一致のインデックスと値が報告されます。サイズが一致しない場合は、それも報告されます(そして、ベクトルの終わりから実行されるだけではありません)。


非PODタイプを使用するBOOST_CHECK_EQUAL場合、または使用する場合は、実装する必要があることに注意してくださいBOOST_CHECK_EQUAL_COLLECTIONS

bool YourType::operator!=(const YourType &rhs)  //  or OtherType
std::ostream &operator<<(std::ostream &os, const YourType &yt)

それぞれ比較とロギングのために。
渡されるイテレータの順序によってBOOST_CHECK_EQUAL_COLLECTIONS、比較のRHSとLHSのどちらかが決まり!=ます。最初のイテレータ範囲は、比較のLHSになります。

于 2010-10-22T18:08:48.140 に答える
17

ただし、少しトピックから外れていますが、許容誤差との比較を使用して浮動小数点数のコレクションを比較する必要がある場合は、このスニペットが役立つ場合があります。

// 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);
于 2013-07-06T13:27:17.160 に答える
14

Boost 1.59以降、std::vectorインスタンスの比較がはるかに簡単になりました。バージョン1.63については、このドキュメントを参照してください(これは、この点で1.59とほぼ同じです)。

たとえば、あなたが宣言した場合、std::vector<int> a, b;あなたは書くことができます

BOOST_TEST(a == b);

非常に基本的な比較を行います。これの欠点は、失敗した場合にBoostが通知するだけで、同じaではないことです。bしかし、エレガントな方法で可能な要素ごとに比較することで、より多くの情報を得ることができます

BOOST_TEST(a == b, boost::test_tools::per_element() );

または、辞書式の比較が必要な場合は、

BOOST_TEST(a <= b, boost::test_tools::lexicographic() );
于 2017-03-29T11:22:57.130 に答える
10

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):「テスト」のエラー:チェック{col1、col1 + 7} == {col2、col2+7}が失敗しました。

位置2の不一致:3!= 4

位置5の不一致:6!= 7

*テストスイート「例」で1つの障害が検出されました

于 2010-10-22T18:10:13.117 に答える
5

で使用できますBOOST_REQUIRE_EQUAL_COLLECTIONSが、ベクトルのベクトルまたは値がベクトルであるマップがある場合にstd::vector<T>、Boost.Testを印刷する方法を教える必要があります。std::vectorマップがある場合、Boost.Testに印刷方法を教える必要がありますstd::pairstd::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_COLLECTIONS2つのコレクションが同じサイズであると仮定すると、不一致のアイテムのインデックスと2つのコレクションの内容が表示されます。サイズが異なる場合、それは不一致と見なされ、異なるサイズが印刷されます。

于 2014-08-08T19:45:03.270 に答える