Hacer tests es una de las habilidades que más cuesta dominar a los desarrolladores, y esto es muy normal.
Primero porque hacen falta conocimientos de desarrollo de software de alto nivel para que los tests sean más sencillos de hacer, y segundo porque muchas veces no le vemos el valor.
Hoy vamos a ver las razones por las que te cuesta tanto hacer tests, y voy a darte las claves para que a partir de ahora te resulte mucho más sencillo.
De todo esto y mucho más vamos a hablar en la Semana Coders, una semana completa de contenido gratuito con vídeos, sesiones en directo, y muchas sorpresas. Apúntate aquí para no perdértelo.
Aquí van las 7 razones por las que te cuesta tanto hacer tests:
1. No ves la importancia de hacer tests
Tu aplicación funciona sin ellos, lleva haciéndolo todo este tiempo, incluso está en producción y la gente la usa. ¿Para qué vas a perder tiempo en escribir tests?
Hay literalmente decenas de motivos, pero te voy a dar algunos para que te animes a realizar tests en tu día a día
Te ayuda a estructurar tu código de forma más escalable
Esto va a estar relacionado con otro punto, pero para hacer tests el código necesita ser testable, y eso te obliga a seguir buenas prácticas en tu código.
Indirectamente escribir tests es también bueno para la salud del código base
Te cubren las espaldas frente a cambios
Seguro que te ha pasado muchas veces que has hecho un cambio en una parte de tu código y, no sabes muy bien cómo, eso ha afectado al otro extremo de la App.
Esto puede incluso ser peor, y provocar errores y excepciones que hagan que tu app crashee en lugares totalmente impredecibles.
Esto es el día a día en una App sin tests: cuando tocas algo no sabes si lo que ya existía sigue inalterado, o si ese cambio va a generar problemas.
Si tienes tests que lo validen, esos tests empezarán a fallar.
Son la mejor documentación del código
Escribir comentarios puede ser útil en algunas situaciones. No vamos a entrar aquí en el debate sobre si los comentarios son útiles o no (aunque salvo casos muy particulares la respuesta sea que no).
Pero lo que está claro es que es muy fácil que un comentario se vuelva obsoleto. Puedes cambiar la parte del código a la que hace referencia ese comentario, y nada ni nadie te va a avisar de que el comentario ya no tiene validez.
Por el contrario, los tests pueden ser una muy buena declaración de intenciones. Estos tests definirán lo que una clase tiene que hacer, y si la clase deja de hacerlo, entonces el test fallará.
Pueden evitar que cualquier error vuelva a producirse
Una de las formas en las que más me gusta usar los tests es la siguiente: si detectas un error, escribe un test que falle debido a ese error, y soluciónalo para que el test pase.
A partir de ese momento, si el fallo se vuelve a producir, el test fallará y te enterarás muy rápido.
Las bases de código suelen tener puntos frágiles que son los que fallan más habitualmente. Si no tienes tiempo de refactorizar para que aquello se vuelva más estable, al menos que los tests te cubran.
Puedes refactorizar con seguridad
Refactorizar consiste en, sin cambiar la funcionalidad, reescribir el código que la realiza.
Esto muchas veces es necesario por distintos motivos, por ejemplo porque el código es muy frágil, dífícil de entender, o porque no permite una nueva funcionalidad que tenemos que implementar.
Refactorizar sin tests no es refactorizar, es jugar a la ruleta rusa. Y además en este caso el cargador tiene muchas balas.
Si no quieres jugártela, necesitas una base de tests sobre el código que vas a refactorizar.
Vista esta parte, vamos a por la segunda, que es un clásico
2. Mi jefe no me da tiempo para hacer tests
Esto ocurre en el 99% de las empresas, vamos a ser sinceros…
Te jefe no tiene ni idea de qué son los tests ni para qué sirven (aunque quizá ahora le puedes pasar este vídeo), y por tanto no le ve el valor a que escribas código extra que no va dirigido a crear nuevas funcionalidades.
Pero el responsable de la calidad de tu código no es tu jefe, eres tú. Un profesional responsable debe cuidar su base de código, y eso implica escribir tests que lo validen.
Así que aquí no es que tu jefe no te deje tiempo para hacer tests, es que los tests forman parte de tu trabajo. A un albañil nadie tiene que decirle que sus ladrillos tienen que estar bien puestos: los pone los ajusta, y se asegura de que cada ladrillo está bien alineado antes de poner el siguiente.
Cuando hagas estimaciones de tu trabajo, hazlos contando con que vas a tener que escribir tests. Si aún así siempre te ponen problemas con los tiempos, y te piden hacer las cosas demasiado rápido, quizá deberías buscar una vía de salida y plantearte moverte a un nuevo empleo. Al final es tu profesionalidad lo que está en juego.
3. No estás siguiendo el Principio de Responsabilidad Única
Hay muchos principios y reglas que entran en juego a la hora de escribir tests, pero quizá el Principio de Responsabilidad Única sea el más importante.
Cuando un módulo hace muchas cosas, se vuelve imposible de testear. Esto es porque hace tantas cosas que no puedes estar seguro de qué falla, ni puedes crear una serie de tests que definan lo que ese módulo debería hacer.
Es mejor dividir tu software en componentes pequeños que tengan muy definida su tarea, y hacer tests será mucho más sencillo.
Los principios SOLID en general son una guía esencial para escribir software de calidad, y si te apuntas a la Semana Coders, recibirás de forma gratuita una guía para aprenderlos.
4. No estás siguiendo el principio de Inversión de Control
Si has llegado al punto anterior, ahora te encontrarás con que muchas entidades dependen de otras para hacer su trabajo.
Eso está muy bien, pero durante los tests (principalmente los unitarios), no deberías depender de ellos para probar tu código, porque si algo falla no sabrás quién es el culpable.
Además esos componentes pueden estar realizando operaciones pesadas, o incluso peticiones a componentes externos, y no vas a querer que tus tests dependan de eso. Al menos no todos.
Para ello, en vez de crear las dependencias en tu componente, necesitas que alguien te las provea. Esto es lo que se denomina Inversión de Control: las dependencias nos son dadas, normalmente a través del constructor.
Ahora la cosa mejor, porque ya puedes sustituir esas dependencias por otras sobre las que tú tengas el control. Pero para hacer esto necesitas un paso más…
5. No estás usando el Principio de Inversión de Dependencias
Otro de los principios SOLID que aquí cobra todo el sentido. Por mucho que extraigamos las dependencias, si no las podemos sustituir por variaciones de esas clases adaptadas a la necesidad del test, entonces no estamos haciendo gran cosa.
Es por ello que en vez de depender de concreciones, nuestros módulos deben depender de abstracciones, normalmente interfaces o clases abstractas.
De esa forma, podemos implementar la interfaz y darle el comportamiento que queramos para el test, sin depender de lo que haga realmente. Esto en el mundo de los tests se conoce como Fakes o Mocks.
Algunas herramientas como Mockito nos pueden ayudar a simplificar este paso, pero conviene usar estas herramientas de mocking con cuidado.
6. No estás utilizando un inyector de dependencias
Este punto en particular no sabía si añadirlo, porque realmente para hacer tests no necesitas un inyector, pero sí para que tu código no se vuelva impracticable. Al tener ahora que proveer todas las dependencias en vez de ser cada componente el que las instancia, alguien se tiene que encargar de esto.
Si lo hacemos en cualquier lado, estaremos complicando en exceso el código y rompiendo el Principio de Responsabilidad Única.
Así que lo ideal es buscarse un proveedor de dependencias. En el título he dicho inyector, pero también puede ser un service provider, o incluso una implementación casera.
Si usas una librería, normalmente todas te explican cómo sustituir las dependencias durante los tests, que para tests de integración pueden ser de utilidad.
7. Tu arquitectura no está preparada para tests
En realidad esta es una generalización de las demás, ya que todos los puntos anteriores se podrían englobar aquí.
Una arquitectura bien dividida por capas, donde las capas más externas no se acoplen en las internas, hará que los tests sean mucho más sencillos.
Si tus componentes dependen de librerías externas, y estas librerías no están abstraídas de ninguna forma, no vas a poder deshacerte de ellas cuando quieras probar ese componente te va a ser imposible.
Seguir una arquitectura por capas como Clean Architecture, una arquitectura hexagonal, unidireccional, etc, te facilitará mucho la tarea.
Todas estas arquitecturas están pensadas para que los tests sean muy sencillos. Así que cuando aprendas una arquitectura, revisa también cómo hacer tests sobre ella.
Conclusión
Como ves, el problema básico de no conseguir hacer tests es que muchas veces los atacamos sin tener claros muchos conceptos previos que nos van a hacer el camino más fácil.
De todo esto y mucho más es de lo que vamos a hablar en la Semana Coders, una semana de training gratuito de la que vas a poder disfrutar muy pronto. Apúntate para no perderte nada.
0 comentarios