Question

J'utilise Test Boost pour test unitaire du code C ++.

J'ai un vecteur de valeurs que je dois comparer avec les résultats attendus, mais je ne veux pas vérifier manuellement les valeurs dans une boucle:

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

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

Le principal problème est que le contrôle de la boucle n'imprime pas l'index, donc il faut un peu de recherche pour trouver le décalage.

Je pourrais utiliser std::equal ou std::mismatch sur les deux vecteurs, mais il faudra beaucoup de passe-partout ainsi.

Y at-il un moyen plus propre de le faire?

Était-ce utile?

La solution

Utilisez BOOST_CHECK_EQUAL_COLLECTIONS . Il est une macro dans test_tools.hpp qui prend deux paires de itérateurs:

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

Il fera rapport sur les indices et les valeurs non-concordance. Si les dimensions ne correspondent pas, il fera rapport que aussi bien (et pas seulement ruisseler la fin du vecteur).


Notez que si vous souhaitez utiliser BOOST_CHECK_EQUAL ou BOOST_CHECK_EQUAL_COLLECTIONS avec des types non-POD, vous devrez implémenter

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

pour la comparaison et l'exploitation forestière, respectivement.
L'ordre des itérateurs transmis à BOOST_CHECK_EQUAL_COLLECTIONS détermine qui est le RHS et LHS du comparateur de != -. La première plage de itérateur sera le LHS dans les comparaisons

Autres conseils

Un peu hors-sujet, cependant, quand parfois on a besoin de comparer les collections de nombres à virgule flottante en utilisant comparison avec la tolérance puis cet extrait peut être utile:

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

Cela n'imprime pas les indices d'un tableau d'éléments désadaptation, mais il n'imprime les valeurs de désadaptation avec une grande précision, de sorte qu'ils sont souvent faciles à trouver.

Exemple d'utilisation:

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

Que diriez-vous 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 );
}
  

exemple

     

Exécution 1 cas de test ...

     

test.cpp (11): erreur "test": {chèque col1, col1 + 7} == {col2, col2 + 7} a échoué.

     

Mismatch en position 2: 3 = 4

     

Mismatch en position 5: 6 = 7

     

* 1 échec détecté dans la suite de test "exemple"

Depuis Boost 1,59, il est beaucoup plus facile de comparer les instances de std::vector. Voir cette documentation pour la version 1.63 (qui est à peu près égale à cet égard à 1,59).

Par exemple, si vous avez déclaré std::vector<int> a, b; vous pouvez écrire

BOOST_TEST(a == b);

pour obtenir une comparaison très basique. L'inconvénient est que, en cas de Boost non seulement vous dit que a et b ne sont pas les mêmes. Mais vous obtenez plus d'informations en comparant élément par élément qui est possible d'une manière élégante

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

Ou si vous voulez une comparaison lexicographique vous pouvez le faire

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

Vous pouvez utiliser

scroll top