En Abril del 2007 di una platica en la UACJ que llevó el mismo título de este post.
Dicha plática se dio dentro de las actividades de la Sociedad de Estudios en Computacion, sociedad que liderea el profesor Saúl González.
Desempolvé este tema porque veo útil mostrar lo que es TDD (Desarrollo Orientado a Pruebas) y cómo TDD ayuda al desarrollo y al mantenimiento de un sistema. Tradicionalmente las pruebas de una aplicación representan una tarea monótona y talachera (entiéndase manual, repetitiva y sujeta al error humano).
Pones a un equipo de monos a ejecutar Test Cases y que Dios nos agarre confesados!!, la idea es que hagan pedazos la aplicación, la idea es que encuentren cual Sherlock Holmes todos los bugs habidos y por haber. Lo cual en la práctica, no es una tarea sencilla, depende de la pericia del tester, depende de que tan bien estén diseñadas las pruebas, depende de muchos factores.
En sistemas complejos, lo que más quieres es controlar esos factores, con TDD puedes controlar que las Pruebas Unitarias se cumplan, las cuales son un factor crucial en los sistemas diseñados bajo el Paradigma de Orientados a Objetos.
Que es TDD?
Es una metodología de desarrollo de Software que consiste en implementar las pruebas unitarias antes de comenzar a escribir el código de un modulo
Las pruebas unitarias consisten en comprobaciones (manuales o automatizadas) que se realizan para verificar que el código correspondiente a un modulo concreto de un sistema funciona de acuerdo con los requisitos del sistema.
Ø Tradicionalmente las pruebas se realizan a posteriori, es decir, después de codificar la funcionalidad
Ø En TDD, las pruebas se preparan antes de comenzar a escribir el código
Primero se escriben los casos de prueba y después se implementa el código necesario para que la prueba pase con éxito
Por lo general las pruebas son métodos que ejecutan una acción específica, por ejemplo:
• CrearUsuario()
• CalcularArea()
• BloquearPassword()
• BorrarFactura()
• SacarLaBasuraPorLasMañanasAntesDeQuePaseElCamionRecolector()
Tipos de pruebas
Hay muchas pruebas que se le pueden (deben) hacer al software antes de liberarlo. De otra forma la calidad no va a estar garantizada. Hoy en día nadie se pondría una vacuna que no paso por años de pruebas, sin embargo en la industria de software aun hay Cromañones que no les cae el veinte con esto de las pruebas.
Existen varios tipos d pruebas, por citar algunos:
• Pruebas de usuario
• Pruebas cruzadas
• Pruebas Unitarias
• Pruebas de regresión
Que son las pruebas Unitarias en TDD?
En TDD una prueba unitaria no es otra cosa que código que permite probar los módulos mediante condiciones de prueba.
Las pruebas son diseñadas por el desarrollador y por los expertos del negocio. Estas pruebas se pueden automatizar usando una herramienta como NUnit. Una ventaja de automatizarlas es la posibilidad de lanzar las pruebas tantas veces como sean necesario. En caso de haber cambios en la funcionalidad al correr la prueba se puede verificar si se siguen cumpliendo las reglas de negocio de los objetos.
Ventajas de usar TDD
• Al escribir primero los casos de prueba, definimos de manera formal los requisitos que esperamos que cumpla nuestra aplicación.
• Al escribir una prueba unitaria, pensamos en la forma correcta de utilizar un módulo que aún no existe.
• Se puede automatizar la ejecución de los casos de prueba (por ejemplo, con ayuda de algún framework de pruebas como NUnit)
• Los casos de prueba nos permiten perder el miedo a realizar modificaciones en el código.
• Los casos de prueba definen claramente cuándo termina nuestro trabajo (cuando pasan con éxito todos los casos de prueba)
• Esta práctica es compatible con el Desarrollo Agil (Agile Development).
• TDD permite fácilmente la refactorización.
• TDD fomenta la disciplina del equipo de programación
Proceso de desarrollo con TDD
• Escribir solo el código necesario, que cumpla con la funcionalidad requerida.
• Pasos de este proceso:
– Diseñar las pruebas unitarias
– Escribir el esqueleto de los modulos (o clases) necesarios para la prueba
– Escribir las pruebas unitarias
– Ejecutar las pruebas unitarias
– Codificar los mínimo requerido para que pase cada prueba unitaria asociada a un modulo.
– Ejecutar la prueba y verificar que pase correctamente.
– Iterar
• Existen un número considerable de herramientas que nos pueden ayudar para automatizar las pruebas unitarias.
• Usualmente son frameworks que permiten rápidamente escribir “código que prueba código”.
• La elección de la herramienta dependerá de la naturaleza del proyecto.
• Algunos de los más conocidos son:
– Microsoft Team System
– NUnit
– MbUnit
– JUnit
– csUnit
– TBrun
– XTest
– y muchos mas
Limitaciones de TDD
Hay que tener precaución al decidir cuándo usar TDD. No es recomendable usar TDD cuando:
- Por la naturaleza de la aplicación no sea factible automatizar las pruebas
- No se tenga un conocimiento solido de la Programación Orientada a Objetos (no es suficiente usar lenguajes orientados a objetos, hay que pensar en objetos)
- El equipo esté formado por desarrolladores poco experimentados. Se requieren fuertes habilidades técnicas y de análisis para producir buenas pruebas.
- Los requerimientos no estén definidos en forma clara.
- No se cuente con expertos en el negocio dentro del equipo
- Exista mucha rotación de personal en el equipo
Si aplicas mal o a medias TDD puedes encontrarte los siguiente problemas:
• Generar pruebas mal diseñadas que no te sirvan para determinar si tus objetos tienen el comportamiento esperado. La calidad de la prueba depende del conocimiento del desarrollador.
• Se puede invertir mucho tiempo en hacer pruebas y dejar corta la fase de construcción.
• Diseñar pruebas poco representativas, que no cumplan con un code coverage que en algún momento dejen de usarse
• Invertir mucho tiempo en hacer las pruebas y no darles mantenimiento, lo cual representa un gasto inútil de tiempo.