Esta semana empezamos a trabajar con @CodeRaguet y Maxi Cruz en la tarea de optimizar el pipeline de deployment. Actualmente tenemos un pipeline de deployment que hace lo siguiente:
- Ante cada cambio en el repositorio obtiene el código
- Compila y corre las pruebas unitarias
- Despliega a un ambiente que «de integración»
- Corre las pruebas de aceptación
- Publica los artefactos
- Publica los pactos (pact)
- Despliega a un ambiente «de demo» donde la aplicación queda disponible para pruebas manuales

La ejecución de este pipeline insume actualmente ~45 minutos y el ~85 % de ese tiempo de ejecución lo consume el paso 4: la ejecución de los tests de aceptación.

Este pipeline representa la primera parte del camino hacia producción y se ejecuta varias veces al día ya que el equipo hace trunk-based development (todos trabajan en master). A continuación de este pipeline hay otro que se dispara manualmente que cubre los ambientes de tests y producción.
Un detalle no menor de esta situación es que si no hacemos nada esta situación va a empeorar gradualmente porque el producto está en constante evolución y todo el tiempo se van a agregando nuevos tests.
El desafió que enfrentamos es reducir el tiempo que insume este pipeline y por ende el tiempo que insume la ejecución de las pruebas aceptación. La estrategia que vamos a intentar implementar es: segmentar los tests de aceptación por grupos de funcionalidades y luego ejecutar cada grupo en paralelo.

En una semana les cuento como nos fue.
¿No consideraron tratar de ir dependiendo menos en los test de aceptación?
El problema, no solo es el tiempo que lleva correrlos. Probablemente, si fallan esos tests, hubo un gran desperdicio en el trabajo que se realizó antes.
Creo que una buena alternativa (incluso superadora) podría ser buscar una manera de asegurar la calidad desde el incio, para no depender de la inspección del producto terminado.
Hola Andrés, gracias por tu comentario.
Tenemos varios mecanismos para asegurar la calidad desde el inicio, comenzando por el hecho de que todo el código se hace programando de a pares. Al mismo tiempo los tests que tenemos se han desarrollado en un contexto de BDD/TDD usando Serenity/Cucumber y en ese sentido los tests son especificaciones ejecutables.
Si esos tests fallan no lo consideramos un desperdicio, sino al contrario, significa que algo no está funcionando como se espera y los tests nos están ayudando a prevenir un problema en producción.
Saludos!
Perdón que vuelva a responder, creo que no se entendió mi punto. Tal vez la palabra desperdicio generó ruido.
Con desperdicio me refería al trabajo que se realizó que luego tenía errores. Cuanto antes se detecte un error, menor es el desperdicio y más simple es corregir el problema. Y, si directamente no hay errores, mejor aún.
En la instancia en la que se realizan esos tests, detectar un error muy probablemente indique un gran desperdicio en el trabajo realizado antes (no en la realización del test).
¿Llegan realmente errores a esta instancia? ¿Justifican esa inversión, esfuerzo, tiempo y mantenimiento?
No conozco el contexto, tal vez no sea posible, pero creo que una opción válida sería invertir esos recursos en fortalecer más aún los tests que se realizan más cerca del desarrollo o que no requieran un entorno tan completo.
Kent Doods habla del «Testing Trophy» https://twitter.com/kentcdodds/status/960723172591992832
Gracias por el aporte Andrés. Lei el link que compartiste, me gustó. Estoy muy de acuerdo en esta frase «how much confidence they bring you that your project is free of bugs». Dada la forma en que trabajamos, me animo a decir que el equipo tiene mucha confianza en los tests. Te cuento un poco más del contexto para que se entienda.
Los tests es lo que primero que se escribe al empezar a trabajar en una funcionalidad, como dije antes se hace BDD/TDD, lo cual implica que se define la funcionalidad en conjunto con el cliente a partir de un conjunto de ejemplos que funcionan como especificación y tests al mismo tiempo. Cuando la funcionalidad está completa y llega al ambiente de tests en general funciona según lo esperado. De hecho el equipo tiene 10+ developers (trabajando en subgrupos/feature-teams) y 1 solo tester. Tal como dice el post que compartiste «You should very rarely have to change tests when you refactor code», es efectivamente lo que ocurre pues los tests creados en un contexto de BDD/TDD están enfocados en comportamientos desde la perspectiva del usuario y no en la implementación concreta. Un punto importante para el equipo es que los tests permiten detectar regresiones sobre funcionalidades que fueron desarrolladas meses atrás.
Volviendo a tu pregunta original: «nuestra dependencia» de los tests de acepción no tiene que ver con detectar bugs al momento de testear, sino al contrario, los tests de aceptación guian el desarrollo y hacen que los potenciales bugs aparezcan antes o que directamente no aparezcan.
El post que compartiste me da la sensación que el autor habla de los tests desde la perspectiva tradicional del testers donde los tests se hacen a posteriori del código a diferencia de nuestro caso que los tests no se hacen principalmente a posteriori.
En fin, esto es lo que hacemos y viene funcionando bien al menos a mi parecer (aclaro que no estuve en el proyecto desde el comienzo y que ahora solo estoy dando una mano con cuestiones de CI/CD/Infra). ¡Saludos!