La programación de pruebas unitarias puede ser una tarea laboriosa, ya que requiere un tiempo que no tendríamos que invertir en caso de no hacerlas.
Desarrollar software sin pruebas unitarias es como jugar al fútbol en la nieve: conforme más pasa el tiempo, más grande se hace la bola y más difícil es manejarla, hasta que llega un momento en que la pelota es más grande que tú y ya no puedes seguir. Sin embargo, utilizando pruebas unitarias es como cuando juegas al fútbol en la playa, al principio te cuesta más, pero cuando tus piernas se han acostumbrado a la arena, puedes seguir jugando sin que la pelota vaya haciendose más grande.
Aunque al principio te cueste tiempo acostumbrarte a este método, las ventajas de usar este tipo de pruebas son muchas, entre ellas podemos decir:
- Los errores son más fáciles de localizar: bastará con ejecutar la batería de “Colecciones de pruebas”, y ver qué módulos no las pasan.
- Los errores están más acotados: cuando un programa falla, muchas veces no sabemos por donde pueden venir los problemas. Con las pruebas unitarias conseguimos acotar los errores, sabiendo qué módulos no están pasando las pruebas unitarias.
- Se reducen los “efectos secundarios”: muchas veces, cuando queremos arreglar algo bajo presión, cometemos otros errores, o no tenemos en cuenta ciertos aspectos, que hacen que el programa deje de funcionar por otro sitio. Incluso a veces, es más peligroso arreglar un error que dejarlo como está, ya que podemos subsanar el error, pero generar otros distintos. Aplicando las pruebas unitarias, es más fácil controlar a “ese potro salvaje” que tenemos por programa, ya que pasando de nuevo la batería de pruebas nos aseguraremos de que todo funciona tal y como esperábamos.
- Se da más seguridad al programador: normalmente, la persona que ha programado un módulo no es la misma que la que tiene que corregir sus errores. Esto crea una sensación de inseguridad al programador, ya que, a la hora de corregir un error, no tiene la certeza de que su corrección no va a afectar a otros módulos que desconoce. Las pruebas unitarias aseguran que una corrección no repercute en otros módulos, y permite al programador centrarse en la corrección del error, y no en la repercusión que puede tener esa corrección.
- Los errores se detectan antes que de otra forma: Cuanto más tiempo permanece un bug en el sistema, más tiempo requiere eliminarlo y más difícil se hace su resolución, ya que el impacto que puede causar la corrección es mucho mayor. De hecho, con pruebas unitarias, la mayoría de los errores de programación se detectan durante la propia etapa de programación, ya que esta no se da por concluida hasta que la unidad pasa su batería de pruebas unitarias.
- Las pruebas funcionales se hacen más sencillas, ya que la mayoría de los aspectos individuales de cada unidad ya están probados a través de las pruebas unitarias. De este modo, las pruebas funcionales deben centrarse sólo en verificar la correcta cooperación de las distintas unidades, y en los funcionamientos generales del programa.
- El programador escribe código de una forma más lógica: cuando un programador sabe que va a tener que escribir pruebas unitarias sobre su software, lo diseña de una forma mucho más simple y accesible para las pruebas, o en definitiva: escribe código más limpio y probable. Esto es debido a que no se crean más dependencias de las necesarias, porque esas dependencias dificultarían mucho las pruebas. Cada vez que parezca necesitarse una nueva dependencia (por ejemplo para llamar a un método de otra clase), el programador se lo va a pensar dos veces, y valorará si realmente es necesario o si hay otros caminos. En muchas ocasiones, se dará cuenta de que hay dependencias que se pueden evitar, consiguiendo así una arquitectura con módulos mucho menos acoplados (con menos dependencias).
Además, si aplicamos la metodología de escribir las pruebas antes que el propio código, este efecto se multiplicará, ya que al escribir las pruebas estaremos haciendo el primer uso del código que vamos a desarrollar después, y como el interfaz público todavía no está definido, lo iremos definiendo conforme escribimos las pruebas.
- Cada prueba se convierte en un ejemplo de uso: cuando vamos a utilizar un conjunto con de clases nuevo, lo primero que solemos hacer es buscar los ejemplos en la documentación y ver si hay alguno que encaje en el uso que queremos darle. Con el conjunto de pruebas, ponemos a disposición un conjunto bastante amplio de ejemplos, que si están completos, abarcan todos los posibles usos de la clase. Además, tenemos la seguridad que siguiendo esos ejemplos, el código funcionará, ya que hay pruebas que nos garantizan su funcionamiento correcto. En definitiva, con las pruebas unitarias matamos dos pájaros de un tipo: probamos nuestro código y escribimos ejemplos para que los demás los consulten.