Frage

Ich bin mit Boost-Test Unit-Test einig C ++ Code.

Ich habe einen Vektor von Werten, dass ich mit dem erwarteten Ergebnissen vergleichen muß, aber ich will nicht manuell die Werte in einer Schleife überprüfen:

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

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

Das Hauptproblem ist, dass der Loopcheck den Index nicht druckt, so dass es einige die Suche erfordert die Diskrepanz zu finden.

I std::equal oder std::mismatch auf den beiden Vektoren nutzen könnte, aber das wird auch eine Menge Text erfordern.

Gibt es einen sauberen Weg, dies zu tun?

War es hilfreich?

Lösung

Verwenden Sie BOOST_CHECK_EQUAL_COLLECTIONS . Es ist ein Makro in test_tools.hpp, die zwei Paare von Iteratoren nehmen:

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

Es wird die Indizes berichten und die Werte, die stimmen nicht überein. Wenn die Größen nicht übereinstimmen, wird es berichten, dass auch (und nicht nur über das Ende des Vektors ausgeführt werden).


Beachten Sie, dass, wenn Sie BOOST_CHECK_EQUAL oder BOOST_CHECK_EQUAL_COLLECTIONS mit nicht-POD-Typen verwenden möchten, müssen Sie implementieren

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

für den Vergleich und die Protokollierung, respectively.
Die Reihenfolge des Iteratoren BOOST_CHECK_EQUAL_COLLECTIONS Ermittelt geleitet, der die RHS und LHS des != Vergleichs -. Der erste Iterator Bereich wird die LHS in dem Vergleichen sein

Andere Tipps

Ein bisschen off-topic, aber wenn manchmal braucht man Sammlungen von Gleitkommazahlen zu vergleichen mit comparison mit Toleranz dann diese Schnipsel von nutzen sein kann:

// 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); \
    } \
}

Dies druckt nicht die Array-Indizes von Elementen unpassenden, aber es hat die unpassenden Werte mit hohen Genauigkeit drucken, so dass sie oft leicht zu finden.

Beispiel Nutzung:

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);

Wie wäre es 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 );
}

Beispiel

Beim Laufen 1 Testfall ...

test.cpp (11): Fehler in "test": Scheck {col1, col1 + 7} == {col2, col2 + 7} ist fehlgeschlagen.

Mismatch in einer Position 2: 3 = 4

Mismatch in einer Position 5: 6 = 7

* 1 Fehler erkannt in Testsuite "Beispiel"

Da-Boost 1.59 ist es viel einfacher std::vector Instanzen zu vergleichen. Siehe diese Dokumentation für Version 1.63 (die in dieser Hinsicht auf 1,59 fast gleich ist).

Wenn Sie zum Beispiel std::vector<int> a, b; erklärt haben, können Sie schreiben

BOOST_TEST(a == b);

einen sehr grundlegenden Vergleich zu erhalten. Der Nachteil dabei ist, dass nur im Falle des Scheiterns-Boost sagt Ihnen, dass a und b sind nicht das gleiche. Aber Sie erhalten mehr Informationen durch den Vergleich elementweise, die auf elegante Weise möglich ist,

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

Oder wenn Sie einen lexikographischen Vergleich möchten Sie tun

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

Sie können mit BOOST_REQUIRE_EQUAL_COLLECTIONS mit std::vector<T>, aber Sie haben Boost.Test zu lehren, wie ein std::vector zu drucken, wenn Sie einen Vektor von Vektoren oder eine Karte, deren Werte Vektoren haben. Wenn Sie eine Karte haben, muss Boost.Test zu lernen, wie std::pair drucken. Da Sie nicht die Definition von std::vector oder std::pair ändern können, müssen Sie dies in einer solchen Art und Weise zu tun, dass der Stream-Operator Sie durch Boost.Test verwendet werden zu definieren, ohne Teil der Klassendefinition von std::vector zu sein. Auch diese Technik ist nützlich, wenn Sie nicht über Strom Einfügen Betreiber an Ihr System im Test hinzufügen wollen nur Boost.Test glücklich zu machen.

Hier ist das Rezept für jede 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 << ']';
}

}

Dieser formatiert die Vektoren als [e1,e2,e3,...,eN] für einen Vektor mit N Elemente und wird für eine beliebige Anzahl von verschachtelten arbeiten Vektoren, z.B. wobei die Elemente des Vektors sind auch Vektoren.

Hier ist das ähnliche Rezept für 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 werden Ihnen sagen, den Index der nicht übereinstimmen Elemente sowie die Inhalte der beiden Sammlungen, unter der Annahme, die beiden Sammlungen von gleicher Größe sind. Wenn sie unterschiedlich groß sind, dann die gedruckt sind, gilt ein Mismatch und die unterschiedlichen Größen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top