¡Solo porque compila no significa que se ejecuta! Esa es la esencia de las pruebas unitarias. Prueba el código.Asegúrate de que está haciendo lo que pensabas que estaba haciendo.
Seamos realistas, si traes una transformación matricial de matlab, es fácil arruinar un signo más o menos en alguna parte. Ese tipo de cosas es difícil de ver. Sin probarlo, simplemente no sabes si funcionará correctamente. Depurar 100 líneas de código es mucho más fácil que depurar 100.000 líneas de código.
Algunas personas toman esto a los extremos. Intentan probar cada cosa concebible. Las pruebas se convierten en un fin en sí mismo.
Esto puede ser útil más adelante durante las fases de mantenimiento. Puede verificar rápidamente para asegurarse de que sus actualizaciones no hayan roto nada.
¡Pero la sobrecarga implicada puede paralizar el desarrollo del producto! Y los cambios futuros que alteran la funcionalidad pueden implicar una gran sobrecarga de actualización de prueba.
(También puede causar problemas con respecto a la multi-threading y orden de ejecución arbitraria.)
En última instancia, a menos que se indique lo contrario, mis pruebas tratan de golpear la tierra de en medio.
Mirar para probar en granularidades más grandes, proporcionando un medio de verificar la funcionalidad general básica. No me preocupo tanto por cada posible escenario de cercado. (Para eso están las macros ASSERT).
Por ejemplo: cuando escribí código para enviar/recibir mensajes por UDP, armé una prueba rápida para enviar/recibir datos usando esa clase a través de la interfaz loopback. Nada sofisticado. Rápido, rápido, & código sucio. Solo quería probarlo. Para asegurarme de que realmente funcionaba antes de construir algo encima.
Otro ejemplo: lectura en las imágenes de la cámara desde una cámara Firewire. Lancé una aplicación GTK & sucia para leer las imágenes, procesarlas y mostrarlas en tiempo real. Otras personas lo llaman prueba de integración. Pero puedo usarlo para verificar mi interfaz Firewire, mi clase de imagen, mi transformación Bayer RGGB-> RGB, mi orientación a la imagen & alineación, incluso si la cámara se volvió a colocar boca abajo. Pruebas más detalladas solo estarían justificadas si esto hubiera resultado insuficiente.
Por otro lado, incluso para algo tan simple como:
template<class TYPE> inline TYPE MIN(const TYPE & x, const TYPE & y) { return x > y ? y : x; }
template<class TYPE> inline TYPE MAX(const TYPE & x, const TYPE & y) { return x < y ? y : x; }
me escribió una línea de 1 MOSTRAR macro para asegurarse de que no había ensuciado el signo:
SHOW(MIN(3,4)); SHOW(MAX(3,4));
Todos Quería hacer era verificar que estaba haciendo lo que debería estar haciendo en el caso general. Me preocupa menos cómo se maneja NaN/+ -Infinity/(double, int) que si uno de los colegas decidió cambiar el orden de los argumentos y se equivocó.
En cuanto a la herramienta, hay muchas cosas para probar la unidad. Si te ayuda, más poder para ti. Si no, bueno, realmente no necesitas ser demasiado elegante.
menudo voy a escribir un programa de prueba que vuelca datos dentro y fuera de una clase, y luego lo imprime todo lo alto con un espectáculo macro:
#define SHOW(X) std::cout << # X " = " << (X) << std::endl
(Por otra parte, muchas de mis clases puede auto- imprimir utilizando un operador incorporado < < método (ostream &). es una técnica increíblemente útil para depurar, así como para la prueba!)
Makefile puede ser trivialmente extendido para generar automáticamente archivos de salida de los programas de prueba, y para automáticamente comparar (diff) estos archivos de salida con anterioridad resultados conocidos (revisados).
No es elegante, tal vez un poco menos que elegante, pero a medida que las técnicas van esto es muy efectivo, rápido de implementar y muy bajo. (Lo cual tiene sus ventajas cuando su gerente desaprueba de perder tiempo en esas cosas las pruebas.)
Una última reflexión os dejo con. Esto me va a marcar, así que ¡NO HAGA!
Hace algún tiempo necesitaba un programa de prueba. Era un entregable requerido. El programa en sí tenía que verificar que otra clase funcionaba correctamente. Pero no pudo acceder a los archivos de datos externos. (No podíamos confiar en dónde se ubicaría el programa en relación con cualquier otra cosa. Tampoco en las rutas absolutas). El marco de pruebas unitarias para el proyecto era incompatible con el compilador que debía usar. También tenía que estar en un archivo. El sistema de archivo de proyecto no admite la vinculación de varios archivos para un programa de prueba modesto. (Los programas de aplicación, seguro. Podrían utilizar las bibliotecas. Pero sólo un único archivo para cada programa de prueba.)
Por lo tanto, Dios me perdone, yo "rompió las reglas" ...
< vergüenza >
Utilicé macros. Cuando se definía una macro #define, los datos se escribían en un segundo archivo .c como inicializador para una matriz de estructuras. Posteriormente, cuando el software fue recompilado, y ese segundo archivo .c (con el array struct) fue #incluido, y la macro #define no se configuró, comparó los nuevos resultados con los datos almacenados anteriormente. Sí, incluí un archivo .c. Oh, la vergüenza de todo.
</vergüenza >
Pero se puede hacer ...