Mr.PlanB Logo
    Volver al blog
    DevOps
    CI/CD
    Testing
    QA
    Pipeline Optimization

    Arreglar un CI lento: reducir de 58 a 14 minutos mejorando QA

    20 de enero de 2026
    8 min de lectura

    Si tu canalización de CI tarda cerca de una hora, la gente te dirá siempre las mismas tres cosas: añade más ejecutores (runners), métele mejor hardware y pon en caché todo lo que no se mueva. A veces eso funciona. Muchas otras veces, solo hace que un sistema ya desordenado sea un poco más rápido resultando frustrante, porque el problema suele residir en un lugar menos vistoso: en QA.

    Ese fue el caso de un equipo cuya canalización promediaba 58 minutos de principio a fin. Sobre el papel, nada parecía especialmente roto. Las compilaciones iban bien, al igual que los pasos de despliegue. El cuello de botella se encontraba directamente en las pruebas automatizadas, que devoraban 42 minutos de cada ejecución.

    Desplegaban aproximadamente diez veces al día, por lo que el cálculo de lo que semejante latencia le hace a un equipo no es difícil. Había cambios de contexto por todas partes y pull requests apilándose, y los desarrolladores enviaban cambios y se desentendían porque "el CI va a tardar un buen rato de todos modos".

    Un mes después, esa misma canalización promedia 14 minutos. Los desarrolladores vuelven a esperar sus resultados y confían en ellos. Las máquinas más rápidas y las herramientas exóticas no tuvieron nada que ver con las mayores mejoras. Esas surgieron de ser sinceros sobre para qué sirven las pruebas y cuándo se necesitan realmente.

    Las canalizaciones lentas cambian hábitos y retrasan el código

    Un CI lento acarrea un peaje psicológico que rara vez aparece en los paneles. Cuando la respuesta tarda una hora, los desarrolladores dejan de preocuparse por ella en tiempo real. Abren una PR, lanzan la canalización y pasan a otra cosa. Cuando falla, el fallo parece desconectado del cambio que lo provocó. Así es como las pruebas rotas se reintentan sin investigar o, peor aún, se ignoran por completo.

    Con el tiempo, los equipos se adaptan de maneras poco saludables. La gente acumula cambios para "hacer que la espera valga la pena". Hacen merge a última hora de la tarde y esperan que nada explote durante la noche. Tratan el CI como un mero trámite en vez de como una red de seguridad.

    La ironía es que estos comportamientos hacen que las canalizaciones sean más lentas y más inestables, lo que refuerza el ciclo. QA se convierte en algo que sufre el código, cuando debería ser algo que lo impulse.

    No todas las pruebas merecen el mismo trato

    El primer gran cambio que introdujo este equipo fue también el más polémico a nivel interno. Dejaron de fingir que cada prueba debía ejecutarse en cada pull request y dividieron su conjunto de tests en dos niveles bien diferenciados.

    La suite crítica se ejecuta en cada PR. Cubre autenticación, pagos y los flujos principales de usuario cuya rotura resultaría catastrófica. Tarda unos siete minutos cuando se ejecuta con eficiencia, y si esta suite falla, nada sale a producción.

    La suite completa sigue existiendo, pero ya no se encuentra en la ruta crítica inmediata. Se ejecuta por las noches y en las ramas de lanzamiento, donde detectar casos límite rebuscados compensa el tiempo adicional.

    El objetivo era ajustar la velocidad de respuesta al nivel de riesgo sin reducir la calidad. La mayoría de los cambios no tocan los rincones más profundos del sistema, y obligar a cada desarrollador a esperar una cobertura exhaustiva en cada commit no hace que el software sea más seguro. Solo hace que los equipos sean más lentos y escépticos. Una vez que ese cambio de mentalidad encajó, todo lo demás resultó mucho más fácil de justificar.

    Paralelizar parece obvio hasta que lo intentas

    Todo el mundo sabe que las pruebas en paralelo son más rápidas. Lograr que funcionen de verdad es otra historia.

    La suite crítica se ejecutaba originalmente en serie, lo que significaba que cada prueba heredaba los problemas de las anteriores, y un paso de configuración lento podía perjudicar a toda la ejecución. Al dividir la suite entre seis ejecutores, el equipo redujo el tiempo de ejecución casi a la mitad de inmediato. Esa fue la mayor victoria sobre el papel.

    Sin embargo, el paralelismo tiene aristas afiladas. Las pruebas que comparten datos, dependen de un estado global o asumen un orden de ejecución concreto suelen desmoronarse al correr una junto a otra. Solucionar eso exigió cambiar el diseño de las propias pruebas; la configuración del CI fue la parte sencilla.

    Cada prueba debía encargarse de su propia inicialización y limpieza, y los recursos compartidos necesitaban aislamiento. Varias pruebas que parecían correctas en serie resultaron ser frágiles desde el principio. Fue un trabajo exigente, pero dio frutos más allá de la velocidad: los tests capaces de correr en paralelo suelen ser, por definición, mejores tests.

    Las pruebas inestables son peores que las lentas

    Si las canalizaciones lentas enseñan a los desarrolladores a ignorar el CI, las pruebas inestables (flaky) les enseñan a desconfiar de él.

    Antes de la reforma, cerca del 18 por ciento de los fallos eran falsos positivos: problemas aleatorios de temporización, tests de interfaz que fallaban porque un botón tardaba unos milisegundos más en renderizarse y errores que desaparecían al volver a ejecutar. Esa cifra es demoledora. Significa que los desarrolladores están condicionados a asumir que el CI les miente casi una de cada cinco veces.

    El equipo abordó esto de raíz sustituyendo las pruebas más problemáticas. Varios tests antiguos de navegador se reescribieron con herramientas más estables. Otros se replantearon por completo, pasando de comprobaciones frágiles de interfaz a enfoques que validaban el comportamiento sin exigir precisión al milímetro.

    El resultado no fue perfecto, pero sí rotundo. Los fallos falsos se redujeron a aproximadamente el tres por ciento, y ese cambio por sí solo probablemente ahorró más tiempo a los desarrolladores que la propia ganancia en velocidad bruta.

    El reintento automático funciona si se usa con rigor

    Una de las decisiones más pragmáticas fue añadir reintentos automáticos para fallos puntuales de pruebas. Si un test falla una vez y pasa en el reintento, la canalización no bloquea la PR, pero marca la prueba para que nada quede oculto bajo la alfombra.

    Este enfoque asume la realidad. Algunos fallos son verdaderamente fortuitos, la infraestructura tiene tropiezos puntuales y los problemas de sincronización se cuelan incluso en pruebas bien diseñadas.

    La responsabilidad en el seguimiento es lo que hace que funcione. Las pruebas reintentadas se registran y revisan, y los patrones saltan a la vista rápidamente. Los tests que exigen reintentos continuos pasan a ser candidatos directos a reparación o eliminación, de modo que el mecanismo de reintento opera como herramienta de diagnóstico en vez de como un parche.

    Sin ese seguimiento posterior, los reintentos pueden ocultar perfectamente regresiones reales. Con él, reducen el ruido mientras empujan el sistema hacia la estabilidad.

    La velocidad devolvió la confianza, y la confianza transformó todo lo demás

    En cuanto la canalización pasó a terminar de forma constante en torno a 14 minutos, los desarrolladores volvieron a esperar al CI. Abrían una PR y observaban cómo se completaban las comprobaciones. Cuando algo fallaba, se sentía inmediato y resoluble, y arreglar una prueba rota ya no suponía perder una hora entera de concentración.

    Esa confianza tuvo efectos en cadena: pull requests más pequeñas, despliegues más frecuentes y menos tentación de subir cambios arriesgados a última hora. La canalización dejó de ser un obstáculo y empezó a integrarse en el flujo natural de trabajo.

    También facilitó las conversaciones con la dirección. Una canalización rápida y fiable es mucho más fácil de defender que una infraestructura costosa que sigue frustrando a todo el equipo.

    El foco costó más que la capacidad de cómputo

    Todo este esfuerzo llevó alrededor de un mes. Las ideas no eran complejas, pero requerían atención continuada sobre las herramientas, las pruebas y los hábitos del equipo.

    Esa es la parte que muchas organizaciones subestiman. Comprar runners más rápidos es sencillo. Reservar tiempo para rediseñar pruebas, reducir la inestabilidad y replantear la estrategia de QA es más difícil, porque compite con el desarrollo de funcionalidades y no entrega nada visible a los clientes.

    Y, aun así, el retorno de la inversión es gigantesco. Los ciclos de respuesta rápidos ahorran energía mental y reducen fricciones además de minutos, haciendo que la ingeniería se parezca menos a esperar y más a construir.

    Arregla QA primero y luego preocúpate por lo demás

    Si tu canalización de CI es lenta, la tentación habitual es empezar por la infraestructura: escalar hacia arriba, optimizar cachés, rascar segundos en las compilaciones. Pero si QA domina el tiempo de ejecución, ahí es donde está la verdadera palanca. Pregúntate qué pruebas necesitan realmente ejecutarse, cuáles son inestables y por qué, y si tu conjunto de tests refleja cómo tu equipo entrega software hoy o cómo lo entregaba hace tres años.

    La mayoría de los equipos tienen un problema de confianza antes que un problema de herramientas. Arreglar QA hará que tu canalización sea más rápida, y también logrará que merezca la pena volver a prestarle atención. Ahí es cuando el CI empieza a cumplir la función que siempre debió tener.