Pruebas unitarias ultrarrápidas con Vitest en proyectos de frontend e IA
Hace un tiempo audité el repositorio de un proyecto en React y TypeScript que contaba con una suite de 400 pruebas unitarias en Jest. Cada vez que lanzabas npm test, tardaba 4 minutos y 15 segundos en completar la ejecución.
Los desarrolladores habían dejado de ejecutar los tests en local. Su flujo de trabajo era hacer git push y esperar a que el servidor de integración continua (CI) les dijera 10 minutos después si habían roto algo.
La fricción era enorme.
Cuando reemplazamos Jest por Vitest y optimizamos el entorno de DOM con happy-dom, la misma suite de 400 tests pasó de tardar 4 minutos a completarse en 7.8 segundos.
En la era del desarrollo acelerado con IA, tener un feedback loop de testing instantáneo no es un lujo; es el único pilar que te permite iterar rápido sin destruir producción.
El problema de Jest en proyectos modernos (Vite / ESM)
Jest fue el rey indiscutible de las pruebas en JavaScript durante casi una década. Sin embargo, su arquitectura arrastra decisiones de diseño pasadas:
- Utiliza transformadores pesados en Babel/ts-jest que recompilan todo tu código TypeScript en CommonJS antes de ejecutar cada test.
- La emulación del DOM con
jsdomconsume gigabytes de memoria Heap en proyectos medianos. - La ejecución en Watch mode rehace trabajo redundante de empaquetado.
Vitest aprovecha la arquitectura moderna de Vite y esm.sh: usa el mismo pipeline de transformación de tu aplicación en desarrollo, comparte la configuración de alias e importaciones y aprovecha hilos de ejecución paralelos en Node.js de forma nativa.
Configuración de Vitest para Frontend e IA
Instalar Vitest en un proyecto moderno requiere un archivo de configuración mínimo (vitest.config.ts):
import { defineConfig } from 39;vitest/config39;;
export default defineConfig({
test: {
environment: 39;happy-dom39;, // Mucho más rápido y ligero que jsdom
globals: true,
setupFiles: [39;./src/test/setup.ts39;],
include: [39;src/**/*.{test,spec}.ts39;],
coverage: {
provider: 39;v839;,
reporter: [39;text39;, 39;json39;, 39;html39;],
},
},
});
Cómo mockear llamadas a Modelos de IA (LLMs) sin gastar tokens
Cuando pruebas código que interactúa con APIs de IA (como Anthropic Claude, OpenAI o Vercel AI SDK), jamás debes realizar peticiones HTTP reales dentro de tus tests unitarios. Lanzarías la factura de tokens por las nubes y harías que tus tests sean no deterministas.
Ejemplo de Mockeo Limpio con vi.mock()
import { describe, it, expect, vi } from 39;vitest39;;
import { procesarRespuestaIA } from 39;./ai-processor39;;
// 1. Mockear la librería cliente de IA
vi.mock(39;@anthropic-ai/sdk39;, () => {
return {
Anthropic: vi.fn().mockImplementation(() => ({
messages: {
create: vi.fn().mockResolvedValue({
content: [{ type: 39;text39;, text: 39;Respuesta mockeada de prueba39; }],
}),
},
})),
};
});
describe(39;Procesador de IA39;, () => {
it(39;debe transformar la respuesta de la IA en una estructura válida39;, async () => {
const resultado = await procesarRespuestaIA(39;Prompt de prueba39;);
expect(resultado.ok).toBe(true);
expect(resultado.texto).toBe(39;Respuesta mockeada de prueba39;);
});
});
Al aplicar programación defensiva en TypeScript, garantizas que tus mocks cumplan exactamente con los contratos de tipos de las librerías originales.
3 Principios para Suites de Test Ultrarrápidas
- Usa
happy-domen lugar dejsdom:happy-domimplementa las APIs del navegador necesarias para componentes de UI ocupando un 70% menos de memoria y ejecutando tests hasta 3 veces más rápido. - Aísla las capas de tu aplicación: Separa los tests de unidades puras (funciones de dominio y utilidades) de los tests de componentes de UI. Al igual que recomendamos en nuestra guía sobre graph engineering, mantener fronteras claras evita inicializaciones innecesarias.
- No intentes testearlo todo: En nuestro análisis sobre cuándo NO usar Spec-Driven Development, recordamos que el objetivo de las pruebas es dar confianza en cambios de producción, no alcanzar el 100% de cobertura en código trivial sin valor de negocio.
La velocidad de ejecución de tus pruebas unitarias determina el ritmo al que tu equipo puede innovar y refactorizar con seguridad.
Si quieres aprender a construir pipelines de testing modernos e integraciones con IA, descubre los Cursos de Dominicode. Y si quieres colaborar en proyectos reales de alto nivel con desarrolladores senior, súmate a Dominicode Labs.
Preguntas frecuentes
¿Es dificil migrar una suite existente de Jest a Vitest?
No. Vitest incluye compatibilidad casi al 100% con las APIs de Jest (describe, it, expect, jest.fn() -> vi.fn()). En la mayoría de los proyectos basta con sustituir la importación y la configuración de jest.config.js por vitest.config.ts.
¿Se pueden ejecutar tests de Vitest en modo Watch continuo durante el desarrollo?
Sí. El modo Watch de Vitest es uno de sus puntos más fuertes: gracias al HMR de Vite, solo reejecuta en milisegundos los tests directamente afectados por el archivo que acabas de modificar en tu editor.
¿Cómo pruebo componentes que utilizan hooks o reactividad de framework?
Vitest se integra perfectamente con @testing-library/react, @testing-library/angular o @testing-library/vue, permitiéndote probar la interacción del usuario con componentes de UI usando la misma sintaxis que ya conoces.
¿Vitest funciona en proyectos que no usan Vite como empaquetador principal?
Sí. Aunque Vitest brilla especialmente en proyectos basados en Vite (como Nuxt, Astro, SvelteKit o React con Vite), puede configurarse y funcionar perfectamente en cualquier proyecto de Node.js o TypeScript independiente.
Por Bezael Pérez — Developer senior con más de 15 años de experiencia y fundador de Dominicode.
