Pruebas en JavaScript: Unit, Integration, E2E — Guía completa
La calidad del código es la clave del éxito de cualquier proyecto. En el mundo de JavaScript (especialmente en Node.js), las pruebas se han convertido no solo en una buena práctica, sino en una necesidad. Analizamos tres niveles clave: pruebas unitarias (unit), de integración (integration) y de extremo a extremo (E2E). Aprenderás en qué se diferencian, cuándo aplicar cada tipo y verás ejemplos prácticos con herramientas populares.
1. Pruebas unitarias: verificamos módulos aislados
Las pruebas unitarias verifican el funcionamiento de funciones, clases o módulos individuales de forma aislada de las dependencias externas (bases de datos, API, sistema de archivos). Es el nivel más rápido y fiable.
Herramientas y configuración
El framework más popular es Jest. Instalación:
npm install --save-dev jestAñade el script en package.json:
"scripts": { "test": "jest"}Ejemplo: probamos la función de cálculo de descuento
Creemos el archivo discount.js:
// discount.jsfunction applyDiscount(price, discountPercent) { if (price <= 0) throw new Error('Price must be positive'); if (discountPercent < 0 || discountPercent > 100) throw new Error('Invalid discount'); return price - (price * discountPercent) / 100;}module.exports = { applyDiscount };Ahora escribimos una prueba unitaria en discount.test.js:
const { applyDiscount } = require('./discount');
describe('applyDiscount', () => { test('calculates 10% discount correctly', () => { expect(applyDiscount(100, 10)).toBe(90); });
test('throws error for negative price', () => { expect(() => applyDiscount(-10, 10)).toThrow('Price must be positive'); });
test('throws error for invalid discount percent', () => { expect(() => applyDiscount(100, 150)).toThrow('Invalid discount'); });});Ejecución: npm test. Jest encontrará automáticamente los archivos *.test.js.
Consejo: Usa objetos mock para aislar de servicios externos.
// Ejemplo de mock de una API externajest.mock('./api');const api = require('./api');api.getData.mockResolvedValue({ id: 1 });2. Pruebas de integración: verificamos la interacción de componentes
Las pruebas de integración verifican cómo funcionan juntos diferentes módulos: base de datos + lógica de negocio + rutas HTTP. Son más lentas que las pruebas unitarias, pero brindan mayor confianza en la corrección del sistema.
Herramientas: Supertest + Jest
Supertest permite hacer peticiones HTTP a tu aplicación Express sin necesidad de iniciar el servidor real.
npm install --save-dev supertestEjemplo: probamos una API REST
Supongamos que tenemos una aplicación Express simple app.js:
const express = require('express');const app = express();app.use(express.json());
app.post('/users', (req, res) => { const { name, email } = req.body; if (!name || !email) { return res.status(400).json({ error: 'Missing fields' }); } // Guardamos en la BD (simplificado) res.status(201).json({ id: 1, name, email });});
module.exports = app;Prueba de integración users.test.js:
const request = require('supertest');const app = require('./app');
describe('POST /users', () => { test('creates user with valid data', async () => { const response = await request(app) .post('/users') .send({ name: 'Alice', email: 'alice@test.com' }); expect(response.status).toBe(201); expect(response.body).toHaveProperty('id'); expect(response.body.name).toBe('Alice'); });
test('returns 400 for missing email', async () => { const response = await request(app) .post('/users') .send({ name: 'Bob' });