← Servidor web y API con Node

Sesión 15 · Semana 5

Probar la API

Hoy · Hoja de ruta

  1. 1. Aprende: Qué se prueba de una API y cómo se escribe una prueba automática con lo que trae Node.
  2. 2. Haz: Escribe la batería de pruebas de tu recurso.
  3. 3. Comprueba: npm test pasa, y falla si rompes algo a propósito.

Antes de empezar · 5 minutos, sin apuntes

  1. ¿Cuántas veces has probado a mano el mismo caso esta unidad?
  2. ¿Cómo sabes hoy que un cambio no ha roto otra cosa?
  3. ¿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 after cierra el servidor. Sin él, el proceso se queda vivo cuando las pruebas ya han terminado y npm test no 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

Lo que no puede faltar
  1. El camino feliz de cada operación
  2. Cada código de error del contrato
  3. Los límites: vacío, cero, el valor de la frontera
  4. La regla de negocio que tiene el proyecto
  5. 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

  1. Añade el script de pruebas al package.json.
  2. Escribe al menos ocho pruebas: caminos felices, errores y límites.
  3. Usa un fichero de datos propio de las pruebas.
  4. Comprueba el contrato: código de estado, forma del cuerpo y campos.
  5. Rompe cada regla a propósito y comprueba que la prueba correspondiente falla.
  6. Deja npm test en verde.
Objetivo mínimoOcho pruebas en verde que cubren éxitos y errores.
Si lo tienesPrueba el servicio directamente, sin HTTP, con un repositorio en memoria.
RetoAñade una comprobación de que ninguna respuesta filtra campos internos.

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 test pasa 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.

  1. ¿Qué debe hacer la aplicación si falta una variable de entorno obligatoria, y por qué?
  2. ¿Qué protege CORS y qué no protege?
  3. Escribe una prueba que compruebe que una entrada inválida devuelve 400.
---