Pregunta

Estoy utilizando la prueba de probar la unidad Boost algo de código C ++.

Tengo un vector de valores que tengo que comparar con los resultados esperados, pero no quiero que comprobar manualmente los valores en un bucle:

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

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

El problema principal es que la comprobación de bucle no se imprime el índice, por lo que requiere un poco de búsqueda para encontrar el desajuste.

Yo podría utilizar std::equal o std::mismatch en los dos vectores, pero eso requerirá una gran cantidad de texto modelo también.

¿Hay una forma más limpia de hacer esto?

¿Fue útil?

Solución

BOOST_CHECK_EQUAL_COLLECTIONS . Es una macro en test_tools.hpp que toma dos pares de iteradores:

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

Se informará de los índices y los valores que el desajuste. Si los tamaños no coinciden, se informará de que también (y no simplemente correr fuera de la final del vector).


Tenga en cuenta que si desea utilizar o BOOST_CHECK_EQUAL BOOST_CHECK_EQUAL_COLLECTIONS con tipos no-POD, que tendrá que poner en práctica

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

para la comparación y la explotación forestal, respectivamente.
El orden de los iteradores pasado a determina BOOST_CHECK_EQUAL_COLLECTIONS que es el RHS y LHS de la comparación != -. La primera gama iterador serán los LHS en las comparaciones

Otros consejos

Un poco fuera de tema, sin embargo, cuando a veces hace falta comparar colecciones de números de punto flotante utilizando comparison con tolerancia continuación, este fragmento puede ser de uso:

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

Esto no imprime los índices de matriz de elementos no coincidentes, pero sí imprimir los valores no coincidentes con alta precisión, por lo que a menudo son fáciles de encontrar.

Ejemplo de uso:

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

¿Qué hay de 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 );
}

ejemplo

Correr el caso 1 prueba ...

test.cpp (11): error en la "prueba": cheque {col1, col1 + 7} == {col2, col2 + 7} falló.

Mismatch en una posición 2: 3 = 4

Mismatch en una posición 5: 6 = 7

* 1 fallo detectado en el banco de pruebas "ejemplo"

Desde Boost 1.59 es mucho más fácil de comparar casos std::vector. Ver esta documentación para la versión 1.63 (que es casi igual a este respecto al 1,59).

Por ejemplo, si usted ha declarado std::vector<int> a, b; puede escribir

BOOST_TEST(a == b);

para obtener una comparación muy básico. La desventaja de esto es que en caso de fallo de Boost sólo le dice que a y b no son lo mismo. Pero se obtiene más información mediante la comparación de elemento a elemento que es posible de una manera elegante

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

O si quieres una comparación lexicográfica puede hacerlo

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

Se puede utilizar BOOST_REQUIRE_EQUAL_COLLECTIONS con std::vector<T>, pero hay que enseñar a Boost.Test cómo imprimir un std::vector cuando se tiene un vector de vectores o un mapa cuyos valores son vectores. Cuando se tiene un mapa, Boost.Test necesita ser enseñado cómo imprimir std::pair. Como no se puede cambiar la definición de std::vector o std::pair, que tiene que hacer esto de una manera tal que el operador de inserción corriente se define será utilizada por Boost.Test sin formar parte de la definición de clase de std::vector. Además, esta técnica es útil si no desea agregar operadores de inserción de flujo en el sistema bajo prueba sólo para hacer feliz Boost.Test.

Aquí está la receta para cualquier 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 << ']';
}

}

Esto da formato a los vectores como [e1,e2,e3,...,eN] para un vector con elementos N y funcionará para cualquier número de vectores anidados, por ejemplo, donde también son vectores de los elementos del vector.

Aquí está la receta similar para 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 le dirá el índice de los artículos que no coinciden, así como el contenido de las dos colecciones, suponiendo que las dos colecciones son del mismo tamaño. Si son de diferentes tamaños, entonces eso es considerado como una falta de correspondencia y se imprimen los tamaños diferentes.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top