Vamos a usar Atheist con el módulo CxxTest, de manera que podamos probar un programa C.
Recordemos algo que yo olvidé: Atheist es una herramienta para pruebas de integración (que tiene como algo adicional la posibilidad de integrarse con python-testunit). Eso quiere decir que nuestras pruebas estarán en C, pero las llamaremos desde Atheist.
Para comenzar, escribimos nuestras pruebas C. Primero sólo vamos a comprobar la interacción entre Atheist y CxxTest (lo saco de los ejemplos de Atheist):
// archivo single_ok.cc
#include <cxxtest/TestSuite.h>
class MyTestSuite : public CxxTest::TestSuite
{
public:
void testAddition( void )
{
TS_ASSERT( 1 + 1 > 1 );
TS_ASSERT_EQUALS( 1 + 1, 2 );
}
};
Ahora creamos el archivo de pruebas atheist:
#archivo cxxtest.test
CxxTest(''$testdir/single_ok.cc'', )
Y ejecutamos:
$ atheist .
[ OK ] TaskCase: ./cxxtest.test
[ ALL OK! ] - 1.28s - 1 test - 1 task
$
Un ejemplo más real
Ahora voy a probar un ejemplo algo más real. Voy a hacer una pequeña función que calcula el factorial de un número. Para ello, necesitaré un archivo con mi función, un archivo de cabecera con la declaración de mi función, y el archivo de pruebas. Vamos al lío:
// archivo factorial.h
#ifndef FACTORIAL_H
#define FACTORIAL_H
#ifdef __cplusplus
extern "C" {
#endif
int factorial (int n);
#ifdef __cplusplus
}
#endif
#endif
//factorial.c
#include "factorial.h"
int factorial (int n) {
return n > 1 ? n * factorial (n-1) : 1;
}
// archivo test_factorial.cc
#include <cxxtest/TestSuite.h>
#include "factorial.h"
class MyTestSuite : public CxxTest::TestSuite
{
public:
void test_factorial_1(void)
{
TS_ASSERT_EQUALS ( factorial(1), 1 );
}
void test_factorial_2(void)
{
TS_ASSERT_EQUALS ( factorial(2), 2 );
}
void test_factorial_3(void)
{
TS_ASSERT_EQUALS ( factorial(3), 6 );
}
void test_factorial_4(void)
{
TS_ASSERT_EQUALS ( factorial(4), 24 );
}
};
#archivo cxxtest.test
CxxTest(''$testdir/single_ok.cc'', )
CxxTest(''$testdir/test_factorial.cc'',
compiling_flags=''-I$testdir'',
objs={''$testdir'': [''factorial.o'']})
Tened en cuenta que, para ejecutarlo, necesitaremos compilar factorial.o, por lo que tendremos:
$ gcc -c factorial.c -o factorial.o
$ atheist cxxtest.test -e
[ OK ] TaskCase: ./cxxtest.test
[ ALL OK! ] - 2.47s - 2 tests - 2 tasks
$
Unas explicaciones
Cuento un poco algunas cosas “raras” que se ven en el código.
Por un lado, vemos que en el archivo factorial.h Hemos incluido unas marcas extrañas:
#ifdef __cplusplus
extern "C" {
#endif
...
#ifdef __cplusplus
}
#endif
Esto se hace así para que C++ “entienda” que lo que se va a definir ahí es C. Cuando compilamos código C++, las funciones se renombran añadiéndoles un prefijo y un sufijo, por lo que hay que indicarle que eso es código C para que el compilador pueda encontrar las funciones.
Por otra parte, hemos necesitado indicarle a Atheist algunos parámetros extra, como son los flags de compilación (sólo hemos necesitado la ruta de los .h), y qué objetos se han utilizado.
Transformando Atheist en una herramienta de generación
No es lo más recomendable, pero podríamos usar Atheist para compilar:
#archivo cxxtest.test
CxxTest(''$testdir/single_ok.cc'', )
Command( ''CC=g++ make $testdir/factorial.o'', shell=True)
t = CxxTest(''$testdir/test_factorial.cc'',
compiling_flags=''-I$testdir'',
objs={''$testdir'': [''factorial.o'']})
Detección de errores
Es normal que ocurra algún problema en la ejecución de CxxTest, ya que realiza pasos muy complejos. Por ello recomiendo utilizar siempre Atheist con las opciones “-e” (mostrar salida de error) y “-o” (mostrar salida estándar).
De esta manera será más sencillo descubrir errores de compilación de CxxTest.