Para evitar o al menos paliar estas cosas, hay una metodologia interesante que se llama test-driven development y que forma parte de la tan cacareada XP (eXtreme Programming).
Esta practica de TDD usa unas herramientas denominadas Unit Test. Unit Test hay para un buen puñado de lenguajes:
Para mi tfc estoy usando cpptest, principalmente por que tiene una caracteristica que lo diferencia del resto: permite comparar resultados en un intervalo. Esa caracteristica para mi es absolutamente fundamental, ya que todo mi tfc tiene valores en coma flotante y no puedo usar una comparacion de igualdad.
La verdad es que es bastante sencillo de usar. Veamos como se comprueba la clase Coordenadas.
Esta clase lo unico que hace es guardar la latitud y longitud de un punto y permite contruir la clase de 3 formas diferentes:
- Teniendo la longitud y la latitud en decimal
- Teniendo la longitud y la latitud en sesagesimal
- Teniendo el par pais/ciudad que previamente existe en una hash
Veamos el ejemplo:
#include <iostream>
#include <stdexcept>
#include <coordenadas.h>
#include <cpptest.h>
class TestCoordenadas : public Test::Suite
{
public:
TestCoordenadas()
{
TEST_ADD(TestCoordenadas::constructor1);
TEST_ADD(TestCoordenadas::constructor2);
TEST_ADD(TestCoordenadas::constructor3);
TEST_ADD(TestCoordenadas::constructor4);
}
private:
void constructor1()
{
Coordenadas test1(34.32, 12.87);
TEST_ASSERT_DELTA(test1.getLongitud(), 0.598997 ,1e-6);
TEST_ASSERT_DELTA(test1.getLatitud(), 0.224624 ,1e-6);
}
void constructor2()
{
Coordenadas test2("Nigeria\\Yola");
TEST_ASSERT_DELTA(test2.getLongitud(),0.217875,1e-6);
TEST_ASSERT_DELTA(test2.getLatitud(), 0.16057,1e-6);
}
void constructor3()
{
TEST_THROWS(Coordenadas(194.32, 12.87), std::domain_error);
}
void constructor4()
{
short pos1[4]={12,38,23,00};
short pos2[4]={-12,59,32,00};
Coordenadas test4(pos1, pos2);
TEST_ASSERT_DELTA(test4.getLongitud(),0.220605 ,1e-6);
TEST_ASSERT_DELTA(test4.getLatitud(), -0.226757,1e-6);
}
};
int main()
{
try
{
Test::Suite ts;
ts.add(std::auto_ptr <Test::Suite> (new TestCoordenadas));
Test::Output* output = 0;
output = new Test::TextOutput(Test::TextOutput::Verbose);
//Test::Output output( Test::TextOutput(Test::TextOutput::Verbose) );
ts.run(*output, true);
}
catch(...)
{
std::cout << "excepcion no esperada\n";
}
return 0;
}
TestCoordenadas::contructor[1|2|4] comprueban que la construccion de la clase es correcta. Creamos una clase y comprobamos que el valor que devuelve getLongitud y getLatitud son correctos y establecemos como intervalo 1e-6. Hay que tener en cuenta que los resultados estan en radianes por que el resto del tfc esta lleno de operaciones de senos y cosenos con las coordenadas.
TestCoordenadas::contructor3 comprueba que la creacion de una coordenada que no existe falla y lazan la excepcion pertienente.
En el constructor de TestCoordendas registramos los test que queremos ejecutar y despues en el mail, incluimos TestCoordenadas en la clase Suite y luego ejecutamos la clase suite para que recorra todos las clases de test. La salida que tendriamos seria:
[raul@maxwell:~/ionoscom/test]./test
TestCoordenadas: 4/4, 100% correct in 0.000280 seconds
Total: 4 tests, 100% correct in 0.000280 seconds
y en el caso de que hubiera un error:
[raul@maxwell:~/ionoscom/test]./test
TestCoordenadas: 4/4, 75% correct in 0.000272 seconds
Test: constructor1
Suite: TestCoordenadas
File: test.cpp
Line: 21
Message: delta(test1.getLatitud(), 0.224624, 1e-6)
Total: 4 tests, 75% correct in 0.000272 seconds
La salida de cpptest es configurable y puede generar HTML texto, texto locuaz (para aquellos que dominan el ingles, verbose ;).
En codeproject, hay una serie de 5 articulos sobre unit test en C# bastate interesante.
Tambien debo tener un ejemplo de la unit test de python en algun sitio del HDD, si lo encuentro, lo añadire.
Los casos de prueba estan muy bien para programas de este tipo, pero que pasa con el resto (que son la gran mayoria). ¿Como se prueba una inferfaz grafica?, ¿Como se le hace un test de regresion a khtml? y un protocolo, ¿que tipo de unit test se empea?.
No acabo de ver muy claro como se prueba el resto de software de manera automatica, asi que entiendo que haya mucha gente que no vea una utilidad clara a las unittest
Iba a poner esto en el wiki de lilo, pero el viernes se piño, y hasta el lunes no creo que vuelva a la vida. Tenemos problemas serios con el suministro electrico.