2009-06-08 22 views
10

Estoy intentando iniciar la prueba unitaria. Estoy viendo algunos frameworks de C++ y quiero probar Boost.Test. La documentación parece muy minuciosa, y es un poco abrumadora, especialmente alguien nuevo en pruebas unitarias. Así que aquí está una situación que quiero:Ayuda para empezar a utilizar Boost.Test

Digamos que tengo 2 clases, Foo y Bar. Quiero escribir un conjunto de pruebas para Foo y un conjunto de pruebas para Bar, preferiblemente en diferentes archivos. Quiero ejecutar las pruebas solo si ejecuto el programa con un parámetro de línea de comando. Así que mi main() debería ser algo como:

int main(int argc, const char* argv[]) 
{ 
    if (argc == 1 && strcmp(argv[0], "-test") == 0) 
     run_all_tests(); 
    else 
     return program_main(argc, argv); 
} 

Creo test_foo.cpp debería ser algo como:

#include "foo.hpp" 
#define BOOST_TEST_MODULE Foo test 
#include <boost/test/unit_test.hpp> 

BOOST_AUTO_TEST_SUITE(Foo_Test) 

BOOST_AUTO_TEST_CASE(Foo1) 
{ 
    Foo f; 
    BOOST_CHECK(f.isValid()); 
} 

BOOST_AUTO_TEST_CASE(Foo2) 
{ 
    Foo f; 
    BOOST_CHECK(f.baz() == 5); 
} 

BOOST_AUTO_TEST_SUITE_END() 

Sin embargo, no sé (1) lo que el comando real para ejecutar las pruebas, es decir, y (2) cómo decir realmente a la biblioteca que quiero ejecutar CADA prueba.

Entonces, ¿quién tiene experiencia con Boost.Test? ¿Alguien puede ayudar de una manera detallada? Muchas gracias.

Respuesta

3

BOOST.La prueba es muy flexible y probablemente puedas hacer lo que quieras. Sin embargo, como dices que eres nuevo en las pruebas unitarias, probablemente deberías seguir la estructura de prueba de la unidad estándar.

Esto es para tener un proyecto de prueba por separado para cada proyecto que está probando la unidad. Luego incluya las fuentes y bibliotecas que necesita para construir el proyecto de prueba.

Esto es más limpio ya que no hay lógica de prueba en su proyecto principal que pueda ejecutarse accidentalmente y es fácil ejecutar las pruebas ya que tienen su propio ejecutable. Este enfoque también funciona para probar bibliotecas. Si sigue esta estructura, encontrará que la mayoría de los valores predeterminados de BOOST.Test funcionan de la caja y usted puede simplemente preocuparse por escribir sus pruebas y códigos.

0

no hay corredor de prueba independiente como en NUnit

sólo tiene que construir los casos de prueba como una única aplicación .exe (si está en Windows) y lo ejecuta

+0

No entiendo ... ¿cómo se ejecuta el programa normalmente (sin pruebas)? – rlbond

+0

básicamente su test_foo.cpp debe compilarse como un programa .exe único y vincularlo a su biblioteca que contiene clases Foo & Bar. Uno de los archivos de cabecera boost.test ya define la función principal, por lo que no creo que lo que usted propuso sea factible. – oscarkuo

+1

Actualmente existe. Se llama console_test_runner. Aunque no es relevante para el problema de OP ya que ya tiene un main. –

12

En su test_foo.cpp, las macros añadir suites de prueba y casos de prueba en en una lista global: master_testsuite, que es la raíz de todos los nodos de prueba . Solo necesita compilar todos los archivos de prueba como test_foo.cpp, test_boo.cpp y un corredor, luego vincularlos todos en el ejecutable .

La función unit_test_main se utiliza para ejecutar las pruebas en master_testsuite.

boost::unit_test::unit_test_main(
    &init_unit_test, 
    argc, 
    argv 
) 

Basado en la macro que define antes de incluir <boost/test/unit_test.h>, Boost.Test ya puede generar la función de main para usted. [1] El generado main simplemente invocó unit_test_main con argc y argv en main. Se recomienda usar unit_test_main porque puede procesar algunos argumentos de consola, como run test by name.

El primer argumento de unit_test_main es un gancho. Dependiendo de BOOST_TEST_ALTERNATIVE_INIT_API, tiene una definición diferente.

#ifdef BOOST_TEST_ALTERNATIVE_INIT_API 
typedef bool  (*init_unit_test_func)(); 
#else 
typedef test_suite* (*init_unit_test_func)(int, char* []); 
#endif 

Puede personalizar el master_testsuite en el gancho. En el segundo formulario , el valor devuelto es el nuevo conjunto de pruebas principal.

[1] Si se definen BOOST_TEST_MAIN y BOOST_TEST_MAIN, pero BOOST_TEST_NO_MAIN no lo es.

5

Puede iniciar las pruebas desde, por ejemplo, un comando de menú, pero no es tan simple y lamentablemente no está bien documentado. Aún más triste: no es posible pasar el camino donde se creará el archivo de registro. Tuve que agregar esa opción de línea de comando yo mismo. Lamentablemente aún no lo he enviado. Mi código es el siguiente:

#ifdef DEBUG 

#undef main 
#define BOOST_TEST_MAIN 
#include <boost/test/included/unit_test.hpp> 

int DoUnitTests() 

{ 
    char *args[] = {"", "--log_level=all", "--auto_start_dbg=yes"}; 

    bool result = ::boost::unit_test::unit_test_main(&init_unit_test_suite, sizeof(args)/sizeof(char*), args); 

    MessageDlog("Unittests result: %s", result ? "ERRORS in Unittests" : "Goooood!"); 
    return result; 
} 

#else 
int DoUnitTests() 

{ 
} 
#endif 
+0

no, no puede iniciar 'char * []' con 'const char * []'. – Abyx

+0

¿De qué estás hablando? Por favor sé más específico. –

+0

Tu código no se compilará. http://coliru.stacked-crooked.com/a/760be4eb168ba404 – Abyx

0

Prueba este guión que escribí, que, dado un nombre del programa y la lista de clases generarán los esqueletos makefile, esqueleto del proyecto y del banco de pruebas para cada clase/módulo. También lo configura todo para que el conjunto de pruebas para cada clase se pueda ejecutar individualmente o como parte de un conjunto global todo en uno.

Es llamada makeSimple y está disponible en sourceforge.