Tests unitarios

Los tests son una forma excelente de asegurarse de escribir aplicaciones estables y libres de errores. Estos, además, sirven como documentación interactiva permitiendo su modificación sin miedo a romper funcionalidad. D, mediante la palabra reservada unittest, proporciona sintaxis nativa como parte del lenguaje para crear bloques de tests unitarios. Los bloques unittest puede aparecer en cualquier parte de los módulos de D para probar funcionalidad.

// Bloque para probar mi función.
unittest {
    assert(myAbs(-1) == 1);
    assert(myAbs(1)  == 1);
}

Esto permite realizar Test-driven development de forma muy sencilla y bajo demanda.

Ejecutar los tests unitarios

Los tests unitarios (bloques unittest) pueden contener cualquier tipo de código. Este código se compila y se ejecuta cuando se pasa la opción -unittest al compilador DMD. El gestor de paquetes de D, DUB, también compila y ejecuta los tests unitarios mediante el comando dub test.

Verificar ejemplos mediante assert

Los bloques unittest contiene típicamente expresiones assert para probar la funcionalidad de una función dada. Estos bloques están generalmente cerca de la definición de la función a probar, que puede ser al principio del código o, incluso, dentro de clases o estructuras.

Incrementar la cobertura del código

Los tests unitarios son una herramienta muy potente para crear aplicaciones a prueba de bala. Una medida común para probar cuánto código fuente de un programa está cubierto por los tests es la cobertura del código (code coverage en inglés). El compilador DMD permite generar de forma sencilla informes de cobertura de código mediante la opción -cov. Para cada módulo se genera un archivo con extensión .lst que contiene estadísticas detalladas sobre dicha cobertura.

Como el compilador es capaz de inferir atributos para código que usa plantillas de forma automática, los tests unitarios se suelen marcar con dichos atributos para asegurarse de que se cumplen en el código probado:

@safe @nogc nothrow pure unittest {
    assert(myAbs() == 1);
}

En profundidad

rdmd playground.d