Skip to content

Esta guía demuestra cómo usar la opción concurrentTestGlob para ejecutar selectivamente pruebas de forma concurrente basándose en patrones de nombres de archivos.

Estructura del Proyecto ​

Estructura del Proyecto
sh
mi-proyecto/
├── bunfig.toml
├── tests/
│   ├── unit/
│   │   ├── math.test.ts          # Secuencial
│   │   └── utils.test.ts         # Secuencial
│   └── integration/
│       ├── concurrent-api.test.ts     # Concurrente
│       └── concurrent-database.test.ts # Concurrente

Configuración ​

Configura tu bunfig.toml para ejecutar archivos de prueba con el prefijo "concurrent-" de forma concurrente:

bunfig.toml
toml
[test]
# Ejecutar todos los archivos de prueba con el prefijo "concurrent-" de forma concurrente
concurrentTestGlob = "**/concurrent-*.test.ts"

Archivos de Prueba ​

Prueba Unitaria (Secuencial) ​

Las pruebas secuenciales son buenas para pruebas que comparten estado o tienen requisitos específicos de orden:

tests/unit/math.test.ts
ts
import { test, expect } from "bun:test";

// Estas pruebas se ejecutan secuencialmente por defecto
let sharedState = 0;

test("adición", () => {
  sharedState = 5 + 3;
  expect(sharedState).toBe(8);
});

test("usa el estado anterior", () => {
  // Esta prueba depende del estado de la prueba anterior
  expect(sharedState).toBe(8);
});

Prueba de Integración (Concurrente) ​

Las pruebas en archivos que coinciden con el patrón glob se ejecutan automáticamente de forma concurrente:

tests/integration/concurrent-api.test.ts
ts
import { test, expect } from "bun:test";

// Estas pruebas se ejecutan automáticamente de forma concurrente debido a que el nombre del archivo coincide con concurrentTestGlob.
// Usar test() es equivalente a test.concurrent() cuando el archivo coincide con concurrentTestGlob.
// Cada prueba es independiente y puede ejecutarse en paralelo.

test("obtener datos de usuario", async () => {
  const response = await fetch("/api/user/1");
  expect(response.ok).toBe(true);
});

// también se puede usar test.concurrent() para marcarlo explícitamente como concurrente
test.concurrent("obtener publicaciones", async () => {
  const response = await fetch("/api/posts");
  expect(response.ok).toBe(true);
});

// también se puede usar test.serial() para marcarlo explícitamente como secuencial
test.serial("obtener comentarios", async () => {
  const response = await fetch("/api/comments");
  expect(response.ok).toBe(true);
});

Ejecutar Pruebas ​

bash
# Ejecutar todas las pruebas - los archivos concurrent-*.test.ts se ejecutarán de forma concurrente
bun test

# Anular: Forzar que TODAS las pruebas se ejecuten de forma concurrente
# Nota: Esto anula bunfig.toml y ejecuta todas las pruebas de forma concurrente, independientemente del glob
bun test --concurrent

# Ejecutar solo pruebas unitarias (secuencial)
bun test tests/unit

# Ejecutar solo pruebas de integración (concurrente debido al patrón glob)
bun test tests/integration

Beneficios ​

  1. Migración Gradual: Migrar a pruebas concurrentes archivo por archivo renombrándolos
  2. Organización Clara: La convención de nombres de archivos indica el modo de ejecución
  3. Rendimiento: Las pruebas de integración se ejecutan más rápido en paralelo
  4. Seguridad: Las pruebas unitarias permanecen secuenciales cuando es necesario
  5. Flexibilidad: Fácil cambiar el modo de ejecución renombrando archivos

Estrategia de Migración ​

Para migrar pruebas existentes a ejecución concurrente:

  1. Comenzar con pruebas de integración independientes - Estas típicamente no comparten estado
  2. Renombrar archivos para que coincidan con el patrón glob: mv api.test.ts concurrent-api.test.ts
  3. Verificar que las pruebas aún pasan - Ejecutar bun test para asegurar que no hay condiciones de carrera
  4. Monitorear problemas de estado compartido - Observar pruebas inestables o fallos inesperados
  5. Continuar migrando pruebas estables incrementalmente - No apresurar la migración

Consejos ​

  • Usar prefijos descriptivos: concurrent-, parallel-, async-
  • Mantener pruebas secuenciales relacionadas juntas en el mismo directorio
  • Documentar por qué ciertas pruebas deben permanecer secuenciales con comentarios
  • Usar test.concurrent() para control fino en archivos secuenciales (Nota: En archivos coincidentes con concurrentTestGlob, test() ya se ejecuta de forma concurrente)

Múltiples Patrones ​

Puedes especificar múltiples patrones para diferentes categorías de pruebas:

bunfig.toml
toml
[test]
concurrentTestGlob = [
  "**/integration/*.test.ts",
  "**/e2e/*.test.ts",
  "**/concurrent-*.test.ts"
]

Esta configuración ejecutará pruebas de forma concurrente si coinciden con cualquiera de estos patrones:

  • Todas las pruebas en directorios integration/
  • Todas las pruebas en directorios e2e/
  • Todas las pruebas con prefijo concurrent- en cualquier lugar del proyecto

Bun por www.bunjs.com.cn editar