Mezcla el orden de tu suite de tests para exponer tests dependientes del orden
Mezcla tus tests y míralos fallar. Si una suite solo pasa en un orden específico, no está probando tu código: está probando un accidente. El estado compartido oculto entre tests es una de las principales causas de builds inestables, y permanece invisible hasta que algo cambia el orden de ejecución: un archivo nuevo, un worker en paralelo, una máquina de CI. Aleatorizar el orden a propósito hace aparecer esas fallas en tu máquina, hoy, en lugar de como un build rojo aleatorio el mes que viene.
Por qué la dependencia del orden se esconde tan bien
En un orden fijo, el test B siempre corre después del test A — así que B hereda en silencio lo que A dejó atrás: un singleton cacheado, un objeto a nivel de módulo mutado, una fila que quedó en la base de datos de prueba, una variable de entorno que nadie limpió. Cada corrida local repite el mismo orden, así que cada corrida local está en verde. Luego CI divide la suite entre workers, o alguien agrega un archivo que ordena antes, y la dependencia se rompe. La falla parece aleatoria; la causa nunca lo fue.
La solución para la detección está a un flag de distancia: haz que el orden aleatorio sea el predeterminado, para que cualquier acoplamiento nuevo falle de inmediato, mientras el commit culpable todavía está arriba.
El flag de shuffle en tu runner
| Runner | Shuffle | Reproducir un orden que falla |
|---|---|---|
| Vitest | --sequence.shuffle.tests (archivos: --sequence.shuffle.files) | --sequence.seed <n> |
| Jest | --randomize (runner jest-circus; imprime el seed) | --seed=<n> |
| pytest | instala pytest-randomly — mezcla automáticamente | --randomly-seed=<n> o --randomly-seed=last |
| Go | go test -shuffle=on (seed del reloj, se reporta en la salida) | go test -shuffle=<N> |
| RSpec | --order rand | --seed 123 (igual que --order rand:123) |
Cada uno imprime o acepta un seed. Ese es todo el flujo: el shuffle encuentra la falla, y el seed la reproduce de forma determinista mientras depuras.
# Vitest: shuffle tests, then replay the exact failing order
vitest run --sequence.shuffle.tests
vitest run --sequence.shuffle.tests --sequence.seed 1734
# pytest with pytest-randomly: rerun the last recorded seed
pytest --randomly-seed=last
Arregla el estado, no el orden
Cuando una corrida mezclada falla, resiste la tentación de fijar el orden de nuevo. La falla te está diciendo que dos tests comparten estado. Soluciones típicas:
- Resetea en el setup, no en el teardown. Un test que crashea se salta su teardown; un setup que parte de un estado limpio conocido es inmune.
- Elimina los mutables a nivel de módulo. Cualquier cosa creada al importar y mutada por los tests es un bug de estado compartido esperando un reordenamiento.
- Fixtures frescas por test. Nueva transacción de BD (con rollback), nuevo directorio temporal, nueva instancia de cliente — un seguro barato contra el acoplamiento.
Notas para usuarios avanzados
- Hazlo permanente en CI. Ejecuta mezclado en cada build; registra el seed en la salida del job para que cualquier build rojo sea reproducible.
- pytest-randomly hace más que reordenar. Antes de cada test también resetea
random.seed()a un valor fijo (y los seeds de NumPy, Faker y factory boy), así que los tests que dependen de aleatoriedad también se vuelven deterministas. Desactívalo temporalmente con-p no:randomlymientras haces bisect. - Introspección del seed en Jest.
--showSeedimprime el seed en el resumen del reporte, yjest.getSeed()lo expone dentro del archivo de test — útil para sembrar tus propios generadores de datos con el mismo valor. - Go reporta el seed de todos modos.
-shuffle=ontoma el seed del reloj del sistema pero siempre imprime el seed, así que una corrida inestable en CI es reproducible después del hecho.
Haz de la independencia del orden una regla, no una esperanza — una suite que pasa en cualquier orden es una suite que puedes paralelizar, dividir y en la que puedes confiar.
Recursos
- Vitest CLI —
--sequence.shuffley--sequence.seed - Jest CLI —
--randomize,--seed,--showSeed - pytest-randomly — plugin de shuffle + reseteo de seed para pytest
- Flags de testing de Go —
go test -shuffle - RSpec —
--order randy--seed
¿Construyendo un flujo de ingeniería asistido por IA? Yeda AI diseña, audita y entrega sistemas LLM de producción.