Extreme Programming
¿Para qué quiero test unitarios?
10 Jul 11
Estoy colaborando junto con Carlos Blé para evolucionar el framework pyDoubles que estamos desarrollando en iExpertos. He comenzado a colaborar con el código bastante avanzado, en su versión 1.1. Me ha tocado estudiar el código antes comenzar a añadirle nuevas características.
Este framework está diseñado desde el principio usando TDD y tiene una cobertura del código con test unitarios cercana al 100%.
Hace unos momentos he acabado de añadirle una nueva funcionalidad que estará disponible para la nueva versión. Se trata de que un spy pueda comprobar que se ha llamado a un método X veces. El código de un test con ello quedaría así:
def test_move_to_cell_severals_times(self):
server_proxy_spy = spy(ServerProxy())
when(server_proxy_spy.move).then_return(("OK", 10))
robot = Robot(server_proxy_spy)
robot.start(total_moves = 2)
assert_that_method(server_proxy_spy.move).was_called().times(2)
El uso de este framework es un API fluída, como puedes observar, por lo que dificulta algo más su desarrollo. Añadir esta funcionalidad nueva, me ha costado alrededor de ¡3 horas únicamente! Lo que sin test unitarios y un buen diseño podrían haber sido varios días.
Gran parte de este mérito lo tienen los test unitarios, surgidos en este caso a partir de un diseño con TDD. ¿Qué me han aportado los test unitarios?
- Me ayudaron a entender el funcionamiento de todo el framework. Sólo me tuve que leer los test y analizar sus implementaciones para comprender y saber usar todas las características de pyDoubles.
- Me sirvieron como documentación de uso cuando tenía dudas sobre cómo usar alguna característica.
- Añadí la nueva funcionalidad con la gran tranquilidad de que el resto de características seguían funcionando.
El resultado final han sido 3 horas para estudiar todo el código del framework y otras 3 horas para añadir la nueva funcionalidad. En menos de una jornada laboral he conseguido saber usar y comprender el código de pyDoubles y añadirle una nueva funcionalidad que no es trivial.
Programar usando TDD, creando sus test unitarios, al principio del proyecto cuesta más tiempo, eso es cierto. Pero:
- ¿Cuánto tiempo ahorrarás en añadir nuevas funcionalidades una vez tu proyecto empiece a tener cierto volumen? Y no hace falta mucho código para que esto ocurra.
- ¿Cuanto tiempo ahorrarás en que otro nuevo desarrollador entre a colaborar en el proyecto y tenga que estudiarse y comprender el código?
- ¿Cuanto tiempo ahorrarás en evitar cometer errores de regresión por no probar todo tu código en cada nueva funcionalidad que añadas? ¿o en cada refactorización?
- ¿Cuánta tiempo ahorrarás en probar todas y cada una de las características y condiciones que tiene tu código?
Estas cuatro preguntas han sido algunos de los grandes males que he sufrido durante años en los proyectos en los que he trabajado. Males que no te dejan hacer bien tu trabajo ya que te quitan tiempo, y todos sabemos que el tiempo el limitado en cualquier proyecto que desarrollas para tus clientes.
Desde mi punto de vista, el ahorro de tiempo es exponencial al tamaño del proyecto. Y no sólo ahorras tiempo, sino que ganas en una gran tranquilidad a la hora de añadir nueva funcionalidades o refactorizar tu código.
Para mi son todo ventajas y se han convertido en parte de mis principios a la hora de desarrollar software.
Puedes leer sobre los resultados reales que hemos tenido aplicando TDD en un post de Carlos Blé escrito recientemente.