MagMax Blog

Aviso: En este blog puede encontrar código!

Atheist: Probando Módulos C

| Comments

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.

Comments