…esto no es un subtítulo…
2015-06-18
Hace tiempo, preparé un sistema de pruebas unitarias para el lenguaje de programación C. Es una cosa sencillísima para proyectos también sencillísimos: consiste en una macro (run_test en el siguiente listado) que acepta como argumento el nombre de un procedimiento que define una prueba unitaria; la macro ejecuta dicha prueba llamando al procedimiento e imprime un mensaje en función del resultado (si la prueba ha sido exitosa o ha fallado). La macro va definida en un fichero (test.h) cuyo contenido es el siguiente:
#ifndef TEST_H
#define TEST_H
/*
* Simple unit testing system for the C programming language.
* Just call run_test with a void -> int test function that returns 1
* if the test passes and 0 if the test fails; run_test will print
* "PASS: " or "FAIL: " and the name of the test function to the
* standard output.
*/
#include <stdio.h>
#define run_test(test) do { \
if ((test)()) puts ("PASS: " #test); \
else puts ("FAIL: " #test); } while (0)
#endif /* TEST_H */
Quizá lo más llamativo es el
do { … } while (0)
,
que es un viejo truco para que una macro que expande a una
secuencia de instrucciones pueda invocarse con un punto y coma al
final, de manera que quede indistinguible de una llamada a función y
sea posible encadenar varias invocaciones en la misma línea sin más
que separarlas mediante el punto y coma.
Un programa en C que ejecutara pruebas unitarias con esta macro podría ser así:
#include <stdlib.h>
#include "test.h"
int
test_1_plus_1_equals_2 (void)
{
return 1 + 1 == 2;
}
int
test_1_plus_1_equals_3 (void)
{
return 1 + 1 == 3;
}
int
main (int argc, char* argv[])
{
run_test(test_1_plus_1_equals_2);
run_test(test_1_plus_1_equals_3);
return EXIT_SUCCESS;
}
Si compiláramos y ejecutáramos este programa, obtendríamos la siguiente salida:
PASS: test_1_plus_1_equals_2 FAIL: test_1_plus_1_equals_3
Categorías: Informática