簡體   English   中英

如何將矢量與Boost.Test進行比較?

[英]How to compare vectors with Boost.Test?

我正在使用Boost Test來測試一些C ++代碼。

我有一個值向量,我需要與預期結果進行比較,但我不想手動檢查循環中的值:

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

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

主要問題是循環檢查不會打印索引,因此需要進行一些搜索才能找到不匹配。

我可以在兩個向量上使用std::equalstd::mismatch ,但這也需要很多樣板。

有更清潔的方法嗎?

使用BOOST_CHECK_EQUAL_COLLECTIONS 它是test_tools.hpp中的一個宏,它接受兩對迭代器:

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

它將報告索引和不匹配的值。 如果大小不匹配,它也會報告(並且不會僅僅在向量的末尾運行)。


請注意,如果要將BOOST_CHECK_EQUALBOOST_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在測試套件中檢測到故障“示例”

從Boost 1.59開始,比較std::vector實例要容易得多。 請參閱此文檔以獲取版本1.63(在這方面幾乎相等於1.59)。

例如,如果你聲明了std::vector<int> a, b; 你可以寫

BOOST_TEST(a == b);

得到一個非常基本的比較。 這樣做的缺點是,如果失敗,Boost只會告訴你ab不一樣。 但是你可以通過比較元素來獲得更多信息,這可能是一種優雅的方式

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

或者,如果您想要進行字典比較,您可以這樣做

BOOST_TEST(a <= b, boost::test_tools::lexicographic() );

你可以將BOOST_REQUIRE_EQUAL_COLLECTIONSstd::vector<T> ,但是當你有一個向量向量或一個值為向量的映射時,你必須教Boost.Test如何打印一個std::vector 當你有一張地圖時,需要教會Boost.Test如何打印std::pair 由於您無法更改std::vectorstd::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 << ']';
}

}

這將向量格式化為具有N元素的向量的[e1,e2,e3,...,eN] ,並且將適用於任何數量的嵌套向量,例如,向量的元素也是向量。

這是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將告訴您不匹配項的索引以及兩個集合的內容。 如果它們具有不同的尺寸,那么這被認為是不匹配的並且印刷了不同的尺寸。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM