learning-front

Nivel 6 · Introducción al testing

Configurar Vitest

Instalar y configurar Vitest en un proyecto con Vite, los scripts de npm (test, watch, coverage), la convención de ficheros .test.ts y el primer test en verde. Por qué Vitest es el runner estándar del ecosistema Vite en 2026.

Ya tienes el porqué del capítulo anterior. Toca el cómo, y empieza por una idea que choca al principio: el testing vive en la terminal, no en el navegador. No abres una página para testear; lanzas un comando, un programa corre tus tests y te devuelve un informe de qué pasa y qué falla. Ese programa es el test runner, y el del ecosistema de Vite es Vitest.

Qué es Vitest y por qué este#

Un test runner hace tres cosas: encuentra tus ficheros de test, los ejecuta y te informa de cuáles pasan (verde) y cuáles fallan (rojo). Tú escribes los tests; él los corre.

En 2026, en un proyecto con Vite (el que montaste en el Nivel 4), el runner por defecto es Vitest, y por buenas razones:

  • Es rápido. Reaprovecha la misma maquinaria de Vite que ya usa tu proyecto para transformar el código, así que no monta un sistema aparte.
  • Entiende TypeScript y los módulos ESM sin configurar nada. Escribes import y .ts y funciona; no hay que montar un transpilador a mano.
  • Trae modo watch. Se queda vigilando y vuelve a correr solo lo que tu cambio afecta.
  • Su API es casi idéntica a la de Jest, el runner clásico. Lo que aprendas aquí te sirve si algún día caes en un proyecto con Jest: cambian cuatro detalles, no el modelo mental.

Instalarlo#

Vitest se instala como dependencia de desarrollo: lo necesitas para programar y para tu pipeline, pero no forma parte de lo que se despliega a los usuarios.

shell
# -D = devDependency: herramienta de desarrollo, no va al bundle de producción.
pnpm add -D vitest

Recuerda la distinción del Nivel 4: en dependencies va lo que se ejecuta en producción (React, Zod); en devDependencies, lo que solo usas tú al desarrollar (Vitest, ESLint, los tipos).

Los scripts de npm#

En vez de teclear el comando completo cada vez, lo dejas con nombre en package.json:

json
{
  "scripts": {
    "test": "vitest run",
    "test:watch": "vitest",
    "coverage": "vitest run --coverage"
  }
}
  • pnpm test → corre la suite una vez y termina (vitest run). Es el que usará tu CI.
  • pnpm test:watchvitest a secas se queda en modo watch.
  • pnpm coverage → corre y además mide la cobertura (cuánto código tocan tus tests; lo veremos a fondo al final del nivel).

La convención .test.ts#

Vitest no necesita que le listes tus tests: los reconoce por el nombre del fichero. Cualquier fichero acabado en .test.ts (o .spec.ts) se considera un test y se ejecuta solo.

Lo habitual es colocar el test junto al fichero que prueba, con el mismo nombre:

text
src/
  motor.ts          ← el código
  motor.test.ts     ← sus tests, al lado

Así, al abrir la carpeta, ves de un vistazo qué está probado y qué no. (Hay quien los agrupa en una carpeta tests/ aparte; las dos formas valen, pero co-locar es lo más común en frontend.)

Tu primer test en verde#

Crea un fichero suma.test.ts con el test más simple que existe: comprobar que dos más dos son cuatro. No prueba nada de tu dominio todavía; solo confirma que la maquinaria corre.

typescript
// suma.test.ts
// describe/it/expect se importan desde "vitest" (sin globals mágicos).
import { describe, it, expect } from "vitest";

// describe agrupa los tests de un mismo tema bajo un título.
describe("primer test", () => {
  // it declara un caso concreto, descrito en lenguaje llano.
  it("2 + 2 son 4", () => {
    // expect afirma el resultado; toBe lo compara con lo esperado.
    expect(2 + 2).toBe(4);
  });
});

Lánzalo con pnpm test y verás algo así en la terminal:

text
 ✓ suma.test.ts (1 test) 2ms
   ✓ primer test > 2 + 2 son 4

 Test Files  1 passed (1)
      Tests  1 passed (1)

Ese en verde es tu primer test pasando. Enhorabuena: la red de seguridad está colgada.

Modo watch: el bucle apretado#

Mientras desarrollas, no lances pnpm test a mano una y otra vez. Arranca pnpm test:watch y déjalo corriendo en una terminal: cada vez que guardas un fichero, Vitest vuelve a correr solo los tests afectados por tu cambio, en milisegundos. Escribes código, guardas, miras el verde o el rojo, sigues. Ese bucle inmediato es lo que hace que testear deje de ser un peaje y se vuelva parte natural de programar.

Configurar lo justo#

Vitest funciona sin configuración: si tienes un vite.config.ts, lo lee. Pero declarar un vitest.config.ts deja tus decisiones por escrito y es donde crecerá la config más adelante:

typescript
// vitest.config.ts
import { defineConfig } from "vitest/config";

export default defineConfig({
  test: {
    // entorno node: lógica pura, sin DOM. (Para componentes, "jsdom"; eso es el Nivel 8.)
    environment: "node",
    // qué ficheros son tests.
    include: ["**/*.test.ts"],
    // globals false: importamos describe/it/expect, sin variables globales.
    globals: false,
  },
});

La opción que importa ahora es environment. Como en este nivel probamos lógica pura —el motor del Team Builder, funciones que entran datos y salen datos— basta "node": no hay navegador, ni window, ni DOM. Cuando en el Nivel 8 pruebes componentes de React, cambiarás a "jsdom", que simula un navegador en memoria. Aquí no te hace falta.

Comprueba lo que sabes#

Pregunta 1 de 5

¿Qué es, en una frase, un test runner como Vitest?

Tu turno#

Este ejercicio se hace en local: el testing vive en tu terminal. Clona la carpeta del ejercicio, instala Vitest y deja tu primer test en verde. Cuando lo tengas (o si te atascas), despliega las soluciones y fíjate en el salto de un nivel al siguiente.

Ejercicio · hazlo en local

Pon Vitest en marcha

Parte de un proyecto mínimo (motor.ts ya escrito, package.json sin Vitest). Instala Vitest, añade los scripts, y deja un primer test en verde con pnpm test. Luego sube de nivel: prueba una función real del motor y configura Vitest de forma explícita.

Paso 1: Primer test en verde

  • Instalas Vitest como dependencia de desarrollo (pnpm add -D vitest).
  • Añades el script "test": "vitest run" al package.json.
  • Creas un fichero .test.ts con un test trivial (una suma) y pnpm test lo muestra en verde.

Cómo hacerlo en local

Clona el repositorio del curso, entra en la carpeta del ejercicio y abre el index.html en tu navegador. Toda tu solución va en solucion.js.

git clone <repo>
cd exercises/nivel-6/configurar-vitest
# abre index.html en el navegador y edita solucion.js
Ver soluciones
// suma.test.ts — el primer test, lo más simple posible.
// Su único objetivo: confirmar que Vitest está instalado y corre de verdad.
import { describe, it, expect } from "vitest";

// describe agrupa los tests de un mismo tema bajo un título legible.
describe("primer test", () => {
  // it declara UN caso concreto, descrito en lenguaje llano.
  it("2 + 2 son 4", () => {
    // expect afirma lo que debe pasar; toBe compara el valor con el esperado.
    expect(2 + 2).toBe(4);
  });
});

Por qué este nivel

  • El test más simple posible: una suma. No prueba nada del dominio, y está bien: su único trabajo es confirmar que la instalación funciona y que pnpm test corre de verdad.
  • describe/it/expect importados desde "vitest": la sintaxis literal que usarás el resto del curso.
  • Su límite: no prueba TU código. Es un "hola mundo" del testing; el siguiente paso es apuntar a una función real.