Hoy · Hoja de ruta
- 1. Aprende: Qué se prueba de una API y cómo se escribe una prueba automática con lo que trae Node.
- 2. Haz: Escribe la batería de pruebas de tu recurso.
- 3. Comprueba:
npm testpasa, y falla si rompes algo a propósito.
Antes de empezar · 5 minutos, sin apuntes
- ¿Cuántas veces has probado a mano el mismo caso esta unidad?
- ¿Cómo sabes hoy que un cambio no ha roto otra cosa?
- ¿Qué casos son los que más se olvidan al probar a mano?
El ejecutor incluido
// pruebas/productos.test.js
import { test, describe, before, after } from "node:test";
import assert from "node:assert/strict";
import { crearApp } from "../src/app.js";
describe("API de productos", () => {
let servidor;
let url;
before(() => {
servidor = crearApp().listen(0); // puerto libre
url = `http://localhost:${servidor.address().port}`;
});
after(() => servidor.close()); // si no, el proceso no termina
test("lista los productos", async () => {
const respuesta = await fetch(`${url}/api/productos`);
assert.equal(respuesta.status, 200);
assert.ok(Array.isArray(await respuesta.json()));
});
test("devuelve 404 si no existe", async () => {
const respuesta = await fetch(`${url}/api/productos/99999`);
assert.equal(respuesta.status, 404);
});
test("rechaza un producto sin nombre", async () => {
const respuesta = await fetch(`${url}/api/productos`, {
method: "POST",
headers: { "Content-Type": "application/json", "x-api-key": process.env.CLAVE_API },
body: JSON.stringify({ precio: 10 })
});
assert.equal(respuesta.status, 400);
const cuerpo = await respuesta.json();
assert.ok(cuerpo.detalles.some((d) => d.campo === "nombre"));
});
});
{ "scripts": { "test": "node --env-file=.env.pruebas --test pruebas/" } }
Sin instalar nada: el ejecutor y las aserciones se incluyen con Node. Conviene observar tres detalles que determinan su funcionamiento:
- El
listen(0)pide un puerto libre cualquiera, así que las pruebas no chocan con tu servidor de desarrollo. Ahí se cobra haber separado la aplicación del arranque en la sesión 3. - El
aftercierra el servidor. Sin él, el proceso se queda vivo cuando las pruebas ya han terminado ynpm testno vuelve nunca. - El fichero de entorno propio da a las pruebas su clave y su ruta de datos. Recuerda que la configuración de la sesión 13 corta el arranque si falta una variable obligatoria: sin ese fichero, importar la aplicación desde una prueba mata el proceso antes del primer
assert.
Qué probar
- El camino feliz de cada operación
- Cada código de error del contrato
- Los límites: vacío, cero, el valor de la frontera
- La regla de negocio que tiene el proyecto
- El fallo que ya te costó una tarde
Una prueba que no falla nunca no prueba nada
Después de escribirla, rompe a propósito lo que comprueba y mira si se pone en rojo. Si sigue en verde, la prueba está mal escrita y te está dando una seguridad falsa, que es peor que no tener prueba.
Y usa datos propios de las pruebas, no los tuyos de desarrollo: una batería que depende de que exista el producto 7 falla el día que alguien lo borra.
Tarea 15 · La batería
- Añade el script de pruebas al
package.json. - Escribe al menos ocho pruebas: caminos felices, errores y límites.
- Usa un fichero de datos propio de las pruebas.
- Comprueba el contrato: código de estado, forma del cuerpo y campos.
- Rompe cada regla a propósito y comprueba que la prueba correspondiente falla.
- Deja
npm testen verde.
Cierre de la semana 5
- La configuración vive fuera del código y se comprueba al arrancar.
- Las operaciones que modifican están protegidas.
- Hay límites de tamaño y de frecuencia.
npm testpasa y detecta las roturas.
Ver respuestas
1 · Que pida un puerto libre cualquiera, sin chocar con el de desarrollo.
2 · Romper a propósito lo que comprueba y ver si se pone en rojo.
3 · Los caminos felices, cada error del contrato, los límites y la regla de negocio.
Microprueba semanal 5 · 5–10 minutos
Individual, sin IA y sin apuntes.
- ¿Qué debe hacer la aplicación si falta una variable de entorno obligatoria, y por qué?
- ¿Qué protege CORS y qué no protege?
- Escribe una prueba que compruebe que una entrada inválida devuelve 400.