🥑 ¿Qué tan buen developer te hace escribir tests? y 🍒 otras recomendaciones

Un tema candente en equipos de desarrollo de software. En esta edición, mi opinión y recomendaciones para abordar escribir tests.

🥑 ¿Qué tan buen developer te hace escribir tests? y 🍒 otras recomendaciones
Photo by Kelly Sikkema / Unsplash

Suscríbete para obtener actualizaciones del newsletter, podcast e ideas para impulsar tu carrera en el desarrollo de software.

Por allá por el 2008 cuando empecé mi primer trabajo formal como desarrollador, se hablaba mucho del manifesto ágil de Kent Beck y compañía, junto al concepto de TDD.

Todo eso me hacía sentido y compartía la idea de tener mi código fuente protegido por estos llamados “test unitarios”.

Lo que me chocaba era que no lo veía aplicado en el día a día. Empresas en su mayoría rechazaban la idea de “gastar” más tiempo escribiendo tests y me costaba encontrar referentes que me dieran un piso sólido para aplicarlo en mi trabajo.

Pasaron los años, y me consideraba el que siempre mencionaba el tema de los tests en las reuniones. Seguía pensando que no se aplicaba y que faltaba educación. Pero al tener mayor confianza, empecé a experimentar y agregar tests “a escondidas”.

Ya más cercano al 2022, pude entender que variables como el presupuesto y tiempo de entrega influyen en la ardua tarea de agregar calidad al software.

Aún no sé si tener esta afinidad por escribir tests me ha hecho mejor developer.

Lo que si te puedo decir es que considerarlos, crea una mentalidad muy distinta en un equipo y hace que el software sea menos receptivo a bugs y mal funcionamiento de features que tus usuarios van a estar probando.

Empecemos con algo de contexto.


🌊 La conversación que nunca termina

Probablemente hayas tenido esta conversación más de alguna vez sobre si escribir o no tests. Las posiciones son diversas y yo mismo incluso algunas veces he pecado de ignorante en mis opiniones.

A medida que vas teniendo mayor consideración en otras área del software que no son técnicas, comprendes que un software no puede tener toda la calidad que requiere y que el presupuesto y tiempo de entrega juegan un rol crítico.

Me ha tocado escuchar estas quejas de developers:

  • Tests unitarios que no agregar valor o que prueban lo obvio
  • Código en mal estado y que hace muy difícil agregar tests
  • Nos quedamos sin tiempo para tests porque no se consideró en el presupuesto
  • No es efectivo porque solo una parte del equipo los está creando

Todas las anteriores son válidas. Pero como te comentaba el podcast de esta semana, los argumentos técnicos generalmente no concluyen esta discusión. Si no más bien con la dirección y visión de los managers que deciden cuánta calidad y tiempo se le puede dedicar a escribir tests.


🐛 El tipo de test a elegir

La conversación es distinta dependiendo del tipo de producto. Tiendo a pensar que por ejemplo para un API, las barreras para crear tests son más bajas que para una app web o móvil.

La razón es porque una API usualmente no depende de otras apps para funcionar y hace del testing una experiencia local donde no se consideran llamadas a terceros.

Para una API generalmente escribo tests unitarios y de integración. Un test unitario va a la par con un modelo. Uno de integración prueba una llamada de la API. Por ejemplo, un POST para crear una entidad (usuario, categoría, etc).

Laravel es mi framework preferido y crear tests es una experiencia placentera. Se integra con PHPUnit y tiene varios “helpers” que permiten crear “mocks”. O sea, falsear una tarea o método que requiere de mayor lógica e información para que sea ejecutada (mandar un email, correr una cola, llamar a S3 en AWS, etc).

La situación cambia bastante en un proyecto frontend. A menos, que tengas información estática, una app va a depender de al menos una otra parte para obtener su data.

Es más común en este caso la creación de “mocks” para una API y así no depender de una conexión a internet al momento que estás corriendo tus tests. En proyectos iOS recientes que he trabajado, cada vez que se crea una nueva dependencia, es obligatorio crear un “mock” para los tests. Otra razón para ello, es porque el “mock” actúa como un acuerdo o contrato entre los equipos de API y app.

Pero en el frontend, el tipo de test unitario es el menos común y no te lo recomiendo. Los tests que más entregan valor son los de UI o “end to end” (E2E). Frameworks como Cypress, Jest y Selenium te pueden ayudar a crear estos.

En mi caso particular, he usado Detox para proyectos en React Native y funciona bien usando el pensamiento BDD.


↔️ ¿“Inside out” o “Outside in”?

Así como existen diferencias en los tipos de tests en backend vs frontend, también se pueden considerar otras estrategias.

El primera es “inside out”, que considera comenzar a escribir el test desde la capa más lejana del usuario. Esto resulta muy conveniente cuándo no conocemos completamente la experiencia de usuario. También suele ser una política que se enfoca en solo una capa. Así el trabajo puede ser ejecutado en paralelo por varios miembros del equipo y distintas capas.

El problema con este approach es que require de mucha inversión de tiempo y cómo no se conoce toda la UX, algo del trabajo realizado sea desechado al terminar el proyecto.

Acá es donde entra la otra estrategia “outside in”. Esta trata de imitar el comportamiento del usuario y generalmente los tests son escritos cuando la funcionalidad se ha completado.

Los nombres que le damos y asociamos a estos tests “outside in” tienen mucho más sentido para el equipo, ya que se tiene más conocimiento de las vistas y modelo de datos en general. También a diferencia de los “inside in” es que son mucho más ligeros y simples.

Las desventajas son que estos tests pasarán en “rojo” por mucho tiempo y solo al final podrán tener un “verde” y demostrar su efectividad. Como son hechos en la capa más alta, requieren además de una coordinación de las otras capas para que funcionen correctamente.


✍🏻 Mi experiencia con los tests

Si bien TDD y escribir tests suena de maravillas, soy el primero en admitir que los tests no son siempre mi prioridad. Como te decía arriba, el tiempo y presupuesto afectan la dedicación a escribir buenos tests.

La principal utilidad que he obtenido de ellos es poder entender mejor los modelos y lógica que estoy creando. Los tests generan preguntas que me ayudan a planificar con tiempo casos borde de mi app.

Por otro lado, muchos developers son de la opinión que crear tests te hacen más lento.

Yo lo pienso al revés. Cómo me permiten aprender más rápido de lo que estoy construyendo, en el largo plazo me hacen mejor conocedor del código y tener algo así como un asistente (los tests) que me recuerda constantemente chequear lógica de negocio.

Por último, en varios proyectos tener tests ha sido de extrema ayuda por la rotación de equipo que algunas veces las agencias deben tener para mantenerse a flote.


❌ ✅ ¿Qué hacer y qué no hacer?

Te dejo recomendaciones que me han ayudado a abordar este tema en proyectos de software:

  • Raramente acepta verdades absolutas o dogmas sobre escribir tests. Ignora y desafía el típico “queremos 100% de ‘code coverage’”. Cada proyecto es un mundo nuevo de oportunidades. Algunos clientes no estarán dispuestos a pagar por tests. En cambio otros si dispuestos a agregarle más calidad al producto.
  • Si tienes la capacidad de diseñar y definir el presupuesto para un proyecto, considera gradualmente agregar un porcentaje para tests. Lo puedes “esconder” como un item de calidad. Comienza con un 3% extra y evalua al final si fue acertado o no. La idea es introducir este concepto temprano en el proceso y educar al equipo sobre su importancia.
  • Elige frameworks o SDKs que hagan entretenido y fácil escribir tests. Para mí ha sido Laravel. Con Cypress también lo paso muy bien en el lado del frontend.
  • Escribe tests que te hagan sentido y no por seguir una moda y parecer más profesional. Es mejor crear 2 tests que prueben algo que tu codeaste vs 20 que se hicieron solo por ejemplo, para aumentar el “code coverage”.
  • Si quieres agregar tests a un proyecto que no tienen, y tal cual como si fueras un abogado defensor en un juicio, prepara una presentación concisa con lo que se gana escribiendo tests. Explícalo en términos de un beneficio para el equipo o el impacto de un feature al negocio. Por ejemplo, “este test va a prevenir que haya un crash en la app para que así hayan más visitas” o “este test va a prevenir que los developers cambien la lógica para calcular el precio final de un producto”.

Volviendo a la pregunta inicial, pienso que escribir tests si me han hecho mejor developer por ser menos dogmático / más flexible, entregar un producto con calidad sin arriesgar el presupuesto y tiempo de entrega, y por último educar a mi equipo sobre la importancia de estos.

¿Tú que piensas?


Tweet de la semana

¿Están las micro credenciales reemplazando los títulos universitarios?


Podcast

En el episodio de esta semana el libro "Body of Work", mi modo de trabajo viajando por Europa y más pensamientos sobre tests en software.


Recomendaciones

  • Actualmente, muchos despidos en empresas tech. Pero nada peor que el manejo de estos como en la empresa Pollen. Un post (en inglés) sobre la negligencia y malos tratos a ex-empleados. Un ejemplo para no seguir.
  • Una edición del podcast de Tim Ferris donde se discute si el “tiempo de calidad” require de más tiempo para que así suceda.

Read more