La idea central antes de escribir una sola línea de código
Cuando envías una petición HTTP con Postman, obtienes una respuesta. Un test es un fragmento de JavaScript que Postman ejecuta automáticamente después de recibir esa respuesta, y que verifica que cumple con lo que esperabas.
"Un test no adivina si algo funcionó — lo afirma formalmente."
Diferencia entre mirar el resultado manualmente y verificarlo automáticamente
Sin tests tienes que revisar visualmente el código de estado, el body y los headers. Con tests, Postman hace esa verificación por ti, de forma repetible y automática en toda la Collection.
¿Dónde se escriben?
En la pestaña "Tests" (también llamada "Post-response") de cada request en Postman. Son JavaScript puro que se ejecuta después de recibir la respuesta, con acceso al objeto pm.
1
Envías la petición HTTP
Postman ejecuta el request y recibe la respuesta del servidor.
2
Postman ejecuta tu JavaScript
El código en la pestaña Tests corre automáticamente, con acceso a la respuesta vía el objeto pm.
3
Cada pm.test() produce PASS o FAIL
Los resultados aparecen en "Test Results". Si algo falla, Postman te dice exactamente qué aserción no se cumplió.
Pestaña Tests · JavaScript
// Se ejecuta automáticamente DESPUÉS de recibir la respuestapm.test("El servidor respondió correctamente", function() {
pm.expect(pm.response.code).to.equal(200);
});
// Resultado en Test Results:// ✓ El servidor respondió correctamente
Sección 02
Anatomía de pm.test()
Diseccionando cada parte. Haz clic en cualquier elemento del código.
pm.test("El artista tiene id y nombre", function() {
pm.expect(pm.response.code)
.to.equal(200);
});
pm
pm.test()
Nombre
Callback
pm.expect()
pm.response
Aserción Chai
Valor esperado
Selecciona una parte del código
Haz clic en cualquier elemento para ver su explicación
Cada parte tiene un rol preciso en la estructura del test.
Esta estructura es siempre la misma. Una vez que la entiendes, puedes escribir cualquier test combinando diferentes propiedades de pm.response con diferentes métodos de aserción Chai.
Sección 03
pm.expect() y la biblioteca Chai
Cómo expresar lo que esperas en lenguaje casi natural
Postman usa la biblioteca Chai para las aserciones. Chai permite escribir verificaciones que se leen como inglés. Toda aserción sigue este patrón:
Patrón general
pm.expect( valor_real ) . to.equal / to.be.a / to.have.property ... ( valor_esperado )
↑ ↑ ↑ lo que método Chai lo que obtuviste (la aserción) esperas
Los métodos de Chai se encadenan con puntos. Palabras como to, be, a, an son solo conectores de legibilidad — no cambian el resultado:
Cadenas equivalentes
pm.expect(body).to.be.an('array'); // más legible — "expect body to be an array"pm.expect(body).be.an('array'); // sin "to" — idénticopm.expect(body).an('array'); // mínimo — idéntico
.to.have.property('nombre') se lee: "espero que [objeto] tenga la propiedad 'nombre'"
Chai está diseñado para que el código sea autodocumentado
La negación se agrega poniendo .not antes del método:
Negación con .not
// Afirmativo: body ES un objetopm.expect(body).to.be.an('object');
// Negado: body NO ES un arreglopm.expect(body).not.to.be.an('array');
// ⚠️ En JS: typeof [] === 'object'// Para verificar un objeto puro (no arreglo) se necesitan ambas líneas.
Sección 04
Las aserciones esenciales
Las 8 que más usarás en el curso. Haz clic en una tarjeta.
🎯.to.equal(v)
Igualdad estricta (===). Para código HTTP, id exacto.
🏷️.to.be.a('tipo')
Verifica tipo JS: 'string', 'number', 'boolean'…
📦.to.be.an('array')
Es un arreglo. Diferente de 'object' en JS.
🔍.to.have.property(k)
El objeto tiene la clave. Para verificar el contrato DTO.
📏.to.be.above(n)
Mayor que n. Para length>0, id>0.
🔎.to.include(s)
String contiene subcadena. Para Content-Type, Location.
🈳.to.be.empty
Longitud 0. Para albumes:[] recién creados.
⏱️.to.be.below(n)
Menor que n. Para tiempo de respuesta.
🎯 .to.equal(v) — Igualdad estricta
Verifica que el valor real es exactamente igual al esperado, en valor y tipo. Usa === internamente — 200 ≠ "200".
Ejemplos
// Código HTTP exactopm.test("Status es 200", function() {
pm.expect(pm.response.code).to.equal(200);
});
// Id coincide con la URL /api/artistas/1const artista = pm.response.json();
pm.test("id es 1", () => pm.expect(artista.id).to.equal(1));
🏷️ .to.be.a('tipo') — Tipo JS
Detecta errores de serialización: si activo llega como "true" (string) en vez de true (boolean), esta aserción lo atrapa.
Ejemplos
const a = pm.response.json();
pm.test("nombre es string", () => pm.expect(a.nombre).to.be.a('string'));
pm.test("id es number", () => pm.expect(a.id).to.be.a('number'));
pm.test("activo es boolean", () => pm.expect(a.activo).to.be.a('boolean'));
📦 .to.be.an('array') — Arreglo
En JS, typeof [] devuelve 'object'. Por eso Chai tiene .be.an('array') que usa Array.isArray() internamente — el único modo correcto.
Ejemplos
const body = pm.response.json();
// GET /artistas → colecciónpm.expect(body).to.be.an('array');
// GET /artistas/1 → objeto puro (no arreglo)pm.expect(body).to.be.an('object');
pm.expect(body).not.to.be.an('array'); // necesario en JS// Campo albumes en DetailDTOpm.expect(body.albumes).to.be.an('array');
🔍 .to.have.property(k) — Verificar campo
Si el campo existe, el backend está devolviendo el DTO correcto. Es la forma de verificar el contrato DetailDTO.
Ejemplos
const a = pm.response.json();
// Verifica contrato ArtistaDetailDTOpm.test("Tiene campos DetailDTO", function() {
pm.expect(a).to.have.property('id');
pm.expect(a).to.have.property('nombre');
pm.expect(a).to.have.property('albumes'); // DetailDTO!
});
// Con forEach en colecciones:
body.forEach(x => pm.expect(x).to.have.property('albumes'));
📏 .to.be.above(n) — Mayor que n
Para verificar que un arreglo no está vacío (length > 0) o que un id fue asignado (id > 0).
Ejemplos
pm.expect(body.length).to.be.above(0); // arreglo no vacíopm.expect(nuevo.id).to.be.above(0); // id asignado por BDpm.expect(nuevo.nombre.length).to.be.above(0); // nombre no vacío
🔎 .to.include(s) — Contiene subcadena
Más flexible que .equal(). El Content-Type puede venir como "application/json" o "application/json;charset=UTF-8" — .include() maneja ambos.
Ejemplos
pm.expect(pm.response.headers.get('Content-Type')).to.include('application/json');
pm.expect(pm.response.headers.get('Location')).to.include('/api/artistas/');
pm.expect(err.message).to.include('999'); // mensaje menciona el id buscado
🈳 .to.be.empty — Colección vacía
Verifica longitud 0. Un artista recién creado tiene albumes:[] — debe existir como arreglo y estar vacío.
Ejemplo
const nuevo = pm.response.json(); // POST → recién creadopm.test("albumes inicia vacío", function() {
pm.expect(nuevo.albumes).to.be.an('array'); // debe existirpm.expect(nuevo.albumes).to.be.empty; // sin paréntesis
});
⏱️ .to.be.below(n) — Menor que n
Para tiempo de respuesta. Una API bien implementada no debería tardar más de 500ms en lecturas simples.
Código HTTP es 200 (devuelve el recurso eliminado)
✓
Body contiene el DetailDTO del recurso eliminado
✓
El id del body coincide con el id de la URL
✓
Limpiar con pm.environment.unset()
DELETE /api/artistas/2 — Tests
const del = pm.response.json();
pm.test("Status 200", () => pm.expect(pm.response.code).to.equal(200));
pm.test("Body es DetailDTO", function() {
pm.expect(del).to.have.property('id');
pm.expect(del).to.have.property('albumes');
});
pm.test("Id eliminado es 2", () => pm.expect(del.id).to.equal(2));
pm.environment.unset("artistaId"); // 🧹 limpiar
✓
404 para recurso no encontrado — nunca 200 con null
✓
409 para recurso duplicado — nunca 400
✓
Body del error tiene status, error y message
✓
El message cita el id o campo que causó el error
✓
Body NO tiene campos de un recurso válido (sin nombre, sin albumes)
GET /api/artistas/999 → 404 — Tests
const err = pm.response.json();
pm.test("Status 404", () => pm.expect(pm.response.code).to.equal(404));
pm.test("Body es error, no artista", function() {
pm.expect(err).to.have.property('error');
pm.expect(err).to.have.property('message');
pm.expect(err).not.to.have.property('nombre'); // no es artista
});
pm.test("message menciona el id", () => pm.expect(err.message).to.include('999'));
Sección 07
Tests encadenados
Cómo pasar el id entre requests usando variables de entorno
En una Collection los requests se ejecutan en orden. Puedes guardar el id de un recurso creado con pm.environment.set() y usarlo en requests siguientes con la sintaxis {{artistaId}}.
El id fluye de un request al siguiente vía variables de entorno
1
POST — Crear y guardar el id
Después del 201, guarda el id generado en una variable de entorno.
Request 1: POST
const nuevo = pm.response.json();
pm.test("Status 201", () => pm.expect(pm.response.code).to.equal(201));
pm.environment.set("artistaId", nuevo.id);
// Ahora {{artistaId}} está disponible en toda la Collection
2
GET — Consultar con {{artistaId}}
Usa la variable en la URL: GET /api/artistas/{{artistaId}}