Saltar al contenido principal

Pruebas unitarias JavaScript: Guía integral 2026

Aprende a dominar las pruebas unitarias de javascript con nuestra guía de 2026. Cubre Jest, Mocha, configuración, simulación, CI y consejos para aplicaciones Capacitor y Electron.

Martin Donadieu

Martin Donadieu

Gerente de contenido

Pruebas unitarias JavaScript: Guía integral 2026

Probablemente estás en una de dos situaciones en este momento. O tu proyecto de JavaScript tiene casi ninguna prueba y cada refactor se siente arriesgado, o ya tienes pruebas y la mitad de ellas son lentas, frágiles y extrañamente difíciles de confiar.

Se vuelve peor en Capacitor y aplicaciones de Electron. Una característica simple puede afectar la lógica de negocio compartida, las API del navegador, los plugins nativos, los archivos locales, la comunicación interprocesos y los servicios remotos en el mismo flujo. Si pruebas esas piezas de manera incorrecta, tu conjunto de pruebas se convierte en un laberinto de dependencias falsas. Si las pruebas de manera correcta, obtienes feedback rápido sobre la lógica que se rompe. Las pruebas unitarias del JavaScript no comienzan con la sintaxis de los matchers inteligentes. Comienza con una frontera disciplinada: prueba la lógica pura directamente, aísla los efectos laterales y evita escribir pruebas que se derrumben en el momento en que renombres una función interna.

Índice

Elegir tu marco de pruebas de JavaScript

Elegir tu marco de pruebas de JavaScript

Un proyecto de JavaScript profesional necesita un verdadero ejecutor de pruebas. Los scripts ad hoc y las comprobaciones manuales de la consola no escalan cuando varios ingenieros tocan el mismo códigobase. Necesitas descubrimiento de pruebas, afirmaciones, manejo asíncrono, mocks y una forma de ejecutar todo de manera consistente en desarrollo local y CI.

La orientación actual se está convergiendo en una pequeña serie de opciones de mainstream. Jest, Mocha y Jasmine son repetidamente destacados como los marcos principales, con Jest a menudo se destaca por su estructura de pruebas integradas, afirmaciones, simulación y soporte asíncrono en un paquete, como se muestra en este Laboratorio de pruebas de JavaScript de Pluralsight.

Una tabla de comparación que muestra los marcos de pruebas de JavaScript populares, incluyendo Jest, Mocha, Cypress y Playwright.

¿Por qué un marco no es opcional

El primer error que cometen los equipos es tratar las pruebas unitarias como una actividad secundaria. Eso suele llevar a nombres de archivo inconsistentes, afirmaciones personalizadas que nadie recuerda y ayudantes que solo entiende una persona.

Un marco te da un lenguaje compartido:

  • Estructura de prueba con describe y test o it
  • Assertions con comparadores legibles Hooks para setup y teardown
  • Soporte asíncrono para promesas y temporizadores Herramientas de simulación para dependencias externas
  • Si su equipo también necesita una visión más amplia de la automatización de pruebas más allá del trabajo a nivel de unidad, __CAPGO_KEEP_0__ tiene una útil visión general de pruebas automatizadas en flujos de entrega de aplicaciones
  • Jest vs Mocha a la vista Jest y Mocha representan dos filosofías diferentes

Capgo __CAPGO_KEEP_0__.

__CAPGO_KEEP_0__

__CAPGO_KEEP_0__

Jest es la opción todo en uno. Envía la mayoría de lo que las equipos necesitan desde el primer día.
Mocha es más modular. Te da un ejecutor y espera que assembles el resto de la pila.

CaracterísticaJestMocha
Complejidad de configuraciónMenor para la mayoría de los equiposMayor porque normalmente agregas bibliotecas de afirmaciones y simulación
AfirmacionesIncluidasNormalmente se combina con otra biblioteca
SimulacroIntegradoNormalmente se combina con otra biblioteca
Pruebas asíncronasIntegrado y directoSoportado, pero depende más de la configuración circundante
Flujo de coberturaComúnmente integrado en la misma cadena de herramientasA menudo más ensamblado
Mejor ajusteNuevos proyectos, equipos que quieren consistenciaPilas legadas, equipos que desean control modular

Regla práctica: Si su equipo tiene que preguntar cuál es la biblioteca de afirmaciones y cuál es la biblioteca de simulación que deben pair con el ejecutor, probablemente quieren Jest.

Lo que recomiendo para la mayoría de los equipos

Para la mayoría de los proyectos modernos, elijo Jest a menos que el código base ya tenga razones sólidas para quedarse en Mocha. Esa recomendación se vuelve más fuerte cuando la aplicación incluye Capacitor o Electron, porque esos proyectos ya tienen suficientes partes en movimiento. Reducir la dispersión de herramientas de pruebas paga rápidamente.

Mocha todavía tiene sentido en servicios de Node.js más antiguos o en códigobases de larga vida donde el ecosistema alrededor de ella ya está asentado. Pero para un ingeniero de nivel medio que está configurando un conjunto robusto desde cero, Jest suele eliminar más fricciones de las que crea.

Nota importante sobre el alcance. Cypress y Playwright son herramientas excelentes, pero resuelven un problema diferente. Son mejores para las comprobaciones de nivel de navegador y fin a fin, no para el rápido bucle interior donde los tests de unidad deben vivir.

Configuración del Proyecto y Tu Primer Test

Un conjunto de pruebas limpio debería ser aburrido. Si agregar el primer test siente complicado, el conjunto probablemente no se mantendrá saludable.

Un hombre con gafas trabajando en un proyecto de programación en una laptop en una mesa de madera.

Una configuración de Jest simple

Comienza con un proyecto de JavaScript que ya tiene un package.jsonLuego agrega Jest como una dependencia de desarrollo y configura un script de test.

{
  "scripts": {
    "test": "jest"
  }
}

Eso es suficiente para muchos proyectos. Puedes agregar más configuración más adelante si tu sistema de módulos, transpilación o estructura de monorepo lo requiere.

Si estás construyendo una aplicación Capacitor localmente y quieres que tu entorno de desarrollo esté en orden antes de agregar tests alrededor de la lógica compartida, Capgo's guía para configurando un entorno local Capacitor es un compañero práctico.

Escribe el test antes de la code

El patrón de prueba en primer lugar no es solo una preferencia personal. La guía de JavaScript de la Oficina de Protección Financiera del Consumidor de los Estados Unidos recomienda explícitamente escribir la prueba primero, organizar las pruebas con describe y it, y formar comprobaciones alrededor de expect(...) afirmaciones en su Guía de pruebas unitarias de JavaScript.

Eso importa porque el cambio a la prueba en primer lugar cambia cómo diseñan code. Las funciones tienden a volverse más pequeñas, las dependencias se vuelven más visibles y los efectos secundarios dejan de filtrarse en la lógica que debe permanecer pura.

Aquí hay un ejemplo mínimo:

// math.js
function addTax(amount, rate) {
  return amount + amount * rate;
}

module.exports = { addTax };
// math.test.js
const { addTax } = require('./math');

describe('addTax', () => {
  it('returns the amount with the tax applied', () => {
    expect(addTax(100, 0.2)).toBe(120);
  });
});

Use Arrange Act Assert cada vez

El Arrange, Act, Assert pattern mantiene las pruebas legibles, incluso cuando crecen más complejas.

  1. Organizar la entrada y cualquier configuración necesaria.
  2. Actuar llamando a la función.
  3. Assertar sobre el resultado.

Aplicado a un ayudante de validación:

function isSupportedPlatform(platform) {
  return ['ios', 'android', 'web', 'desktop'].includes(platform);
}

describe('isSupportedPlatform', () => {
  it('returns true for ios', () => {
    // Arrange
    const platform = 'ios';

    // Act
    const result = isSupportedPlatform(platform);

    // Assert
    expect(result).toBe(true);
  });
});

Las pruebas pequeñas envejecen bien. Una prueba debe responder normalmente a una pregunta, no narrar un flujo de trabajo completo.

Para proyectos de Capacitor y Electron, esa disciplina importa más porque tu lógica pura a menudo se encuentra junto a la integración nativa o de escritorio code. Mantén la regla de negocio probable sin el tiempo de ejecución de la plataforma, y tu primera prueba no será la última útil.

Maestría en Mocks y Asincronos Code

La mayoría de los errores en la aplicación code no provienen de sumar dos números. Proviene de code que se extiende más allá de sí mismo: solicitudes de red, archivos, APIs de plugins, temporizadores, canales de IPC, capas de almacenamiento.

Eso es donde ayuda la simulación. Te da control sobre la frontera para que la prueba se centre en la toma de decisiones de tu code.

Un diagrama de tablero que ilustra una arquitectura de microservicios con APIs, almacenes de datos, servicios externos y flujo de datos impulsado por eventos.

Simula fronteras, no todo

La guía de pruebas mantenibles enfatiza cobertura de un comportamiento y una sola afirmación fuerte por pruebay también advierte que el exceso de simulaciones hace que las pruebas sean frágiles y estrechamente acopladas a detalles de implementación, como se resume en este artículo de TestRail sobre pruebas unitarias mantenibles.

Esa advertencia importa mucho en JavaScript. Los equipos suelen empezar simulando cada módulo importado y terminan probando si las funciones llaman a otras funciones en el "orden correcto", en lugar de probar el comportamiento real.

Objetivo equivocado para una prueba pesada en simulaciones:

  • si el ayudante A llamó al ayudante B
  • ¿Se llamó el servicio C al serializador D
  • ¿Se ejecutó una función interna privada dos veces

Objetivo mejorado:

  • ¿Qué devolvió la función
  • ¿Manejó correctamente una dependencia fallida
  • ¿Transformó los datos en la forma esperada

Un patrón mejorado para Capacitor y Electron code

En aplicaciones móviles y de escritorio, prefiero una capa de envoltura alrededor de APIs nativas o de plataforma. Luego, las pruebas unitarias simulan la capa de envoltura, no la plataforma en sí

Estructura de ejemplo:

// cameraGateway.js
async function getPhoto(cameraPlugin) {
  return cameraPlugin.getPhoto();
}

module.exports = { getPhoto };
// profilePhotoService.js
async function loadProfilePhoto(cameraGateway) {
  const photo = await cameraGateway.getPhoto();
  return { path: photo.path, ready: true };
}

module.exports = { loadProfilePhoto };
// profilePhotoService.test.js
const { loadProfilePhoto } = require('./profilePhotoService');

test('returns mapped photo data', async () => {
  const fakeCameraGateway = {
    getPhoto: jest.fn().mockResolvedValue({ path: '/tmp/pic.jpg' })
  };

  const result = await loadProfilePhoto(fakeCameraGateway);

  expect(result).toEqual({ path: '/tmp/pic.jpg', ready: true });
});

Ese patrón funciona también para Electron. Envuelve ipcRendererPara las integraciones de archivo, acceso a la shell o integraciones detrás de un adaptador delgado. Las pruebas unitarias golpean la capa de servicio, no la ejecución directamente

Para los equipos que están probando la lógica de lanzamiento y los caminos de actualización en Capacitor aplicaciones, Capgo tiene una guía relevante pruebas de actualizaciones OTA con escenarios de simulación Capacitor.

Un breve recorrido ayuda si tu equipo todavía está normalizando el estilo de prueba asíncrono:

Pruebas de flujos asíncronos sin inestabilidad

Usa async/await en las pruebas cuando el code que se está probando devuelve una promesa. Es más claro que los patrones repletos de callbacks y es más fácil de depurar.

async function fetchProfile(api) {
  const response = await api.getUser();
  return response.name;
}

test('returns the user name from the API response', async () => {
  const api = {
    getUser: jest.fn().mockResolvedValue({ name: 'Ava' })
  };

  const result = await fetchProfile(api);

  expect(result).toBe('Ava');
});

También prueba el camino de falla:

test('throws when the API request fails', async () => {
  const api = {
    getUser: jest.fn().mockRejectedValue(new Error('network failed'))
  };

  await expect(fetchProfile(api)).rejects.toThrow('network failed');
});

Prueba tanto el camino feliz como el camino feo. En producción, el camino feo es usualmente el que los usuarios recuerdan.

Estrategias Avanzadas para Pruebas Robustas

Un conjunto de pruebas se vuelve útil cuando sigue siendo útil después de que el code cambia. Eso es más difícil que escribir una pila de pruebas que pasan.

Un diagrama que ilustra estrategias para construir software robusto a través de una cobertura de pruebas completa y conjuntos de pruebas mantenibles.

Usa la división de pruebas como un presupuesto

Una guía práctica recomienda un 70/20/10 across pruebas unitarias, de integración y de sistema, con pruebas unitarias que proporcionan la retroalimentación más rápida y las fallas más estables. La misma guía dice que una suite de pruebas unitarias completa debería terminar en menos de 10 segundos, y las comprobaciones pre-commit deberían mantenerse menos de 5 segundos, según esta guía de pruebas de OpenReplay Trato eso como una herramienta de presupuesto, no una religión. Si la mayor parte de tu esfuerzo se dedica a pruebas de sistema, tu equipo esperará demasiado tiempo para obtener retroalimentación. Si todo es solo unitario, te perderás las verdaderas fronteras del sistema..

Para una aplicación de __CAPGO_KEEP_0__ o Electron, un equilibrio saludable suele verse así:

For a Capacitor or Electron app, a healthy balance usually looks like this:

  • para la lógica de precios, las reglas de permisos, la serialización, la elegibilidad de actualización, las banderas de características y las transformaciones de estado para la lógica de precios, las reglas de permisos, la serialización, la elegibilidad de actualización, las banderas de características y las transformaciones de estado
  • Pruebas de integración para adaptadores de almacenamiento, envolturas de plugins y contratos de IPC
  • Pruebas E2E para unos pocos viajes críticos como inicio de sesión, flujo de compra, sincronización o promt de actualización

La cobertura es una linterna, no un objetivo

Los informes de cobertura son útiles cuando te ayudan a detectar ramas no probadas en lógica importante. Se vuelven perjudiciales cuando los equipos persiguen porcentajes de cobertura por su propio interés

Un validador de inicio de sesión con pruebas de casos de borde pensativas aporta más valor que un archivo cubierto lleno de afirmaciones triviales. Eso es especialmente cierto para entradas pesadas como code tales como formularios, parseadores, lógica de fechas y verificaciones de permisos. Si tu equipo está ajustando la calidad alrededor de la validación pesada de la interfaz de usuario, esta guía sobre la maestría en la validación de formularios de frontend es una buena complementación a la estrategia de pruebas a nivel de unidad

Las pruebas de comportamiento sobreviven a los refactores

Un conjunto confiable debería permitirte refactorizar internos sin volver a escribir la mitad de las pruebas. La forma más fácil de llegar allí es asertar comportamiento observable en lugar de detalles de implementación.

Uso de casos que se sostienen bien:

  • Condiciones de límite como valores de entrada vacíos, valores nulos, tipos inválidos y cadenas de caracteres muy largas
  • Resultados del dominio como “se deniegan devoluciones por falta de permiso”
  • Transiciones de estado como “marca la actualización como pendiente después de validar los metadatos de descarga”

Uso de casos que a menudo se descomponen:

  • inspeccionar llamadas de ayuda internas
  • afirmar la secuencia de métodos privados
  • simular cada capa en la cadena de llamadas

Para equipos de aplicaciones que construyen procesos de liberación disciplinados, el artículo de Capgo sobre la garantía de calidad de aplicaciones es útil porque conecta el trabajo de pruebas con la pipelina de liberación más amplia.

Pruebas para CI, Capacitor, y aplicaciones de Electron

Una prueba que solo se ejecuta en una máquina del desarrollador no es un seguro. Es una costumbre local.

La CI convierte las pruebas unitarias en trabajo JavaScript en infraestructura de equipo. Cada empujón, solicitud de revisión o rama de liberación puede ejercer los mismos comandos con las mismas expectativas. Esa consistencia importa aún más para Capacitor y proyectos de Electron, donde el desplazamiento del entorno causa fallas sutiles.

Hágale a la CI el camino de ejecución por defecto

Al menos, su CI debe instalar dependencias y ejecutar el conjunto de pruebas unitarias en cada conjunto de cambios. Mantenga el comando idéntico a la desarrollo local cuando sea posible.

Un flujo de trabajo básico de GitHub Actions puede ser tan pequeño como esto:

name: test

on: [push, pull_request]

jobs:
  unit:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: '20'
      - run: npm ci
      - run: npm test

Es suficiente para capturar importaciones rotas, afirmaciones fallidas y suposiciones de plataforma accidentales antes de que lleguen a main.

Para equipos móviles que envían a través de pipelines automatizadas, Capgo tiene una guía práctica para configurar CI/CD para aplicaciones de Capacitor.

Pruebas de interacción del plugin Capacitor

La forma incorrecta de probar unidades de Capacitor code es extraer directamente los plugins nativos en cada servicio. Esto acopla tu conjunto de pruebas a la puente de plataforma.

El patrón mejor es una abstracción delgada:

// deviceStorage.js
async function saveFile(filesystem, path, data) {
  return filesystem.writeFile({ path, data });
}

module.exports = { saveFile };
// draftService.js
async function persistDraft(storage, draft) {
  await storage.save('draft.json', JSON.stringify(draft));
  return { saved: true };
}

module.exports = { persistDraft };
// draftService.test.js
const { persistDraft } = require('./draftService');

test('persists a serialized draft', async () => {
  const storage = {
    save: jest.fn().mockResolvedValue(undefined)
  };

  const result = await persistDraft(storage, { title: 'Hello' });

  expect(result).toEqual({ saved: true });
});

La misma idea se aplica a la acceso a la cámara, promt de biometría, registro de tokens de notificación y estado de red. Mantén las llamadas de plugins en adaptadores. Prueba la lógica de la aplicación contra interfaces que controlas.

Pruebas de code del main renderer y IPC de Electron

Las aplicaciones de Electron tienen dos importantes juntas: proceso principal code y proceso de renderizado codeNo las mezcles en las pruebas.

Una configuración confiable separa generalmente:

  • Pruebas unitarias de renderizado para modelos de vista, estado, formateo y lógica de negocio en la interfaz de usuario
  • Pruebas unitarias del proceso principal para menús, operaciones de archivo y decisiones del ciclo de vida de la aplicación
  • Pruebas del contrato de IPC para la forma de mensaje y respuestas esperadas

Ejemplo de envoltura de IPC:

// ipcGateway.js
function sendSettings(ipcRenderer, payload) {
  ipcRenderer.send('settings:update', payload);
}

module.exports = { sendSettings };
// ipcGateway.test.js
const { sendSettings } = require('./ipcGateway');

test('sends settings update over ipc', () => {
  const ipcRenderer = { send: jest.fn() };

  sendSettings(ipcRenderer, { theme: 'dark' });

  expect(ipcRenderer.send).toHaveBeenCalledWith('settings:update', { theme: 'dark' });
});

Si cambias la implementación interna de un helper a otro más adelante, esta prueba sigue siendo válida porque verifica el comportamiento que importa. Ese es el estándar que deseas en escritorio y móvil code.

Preguntas Frecuentes sobre Pruebas Unitarias de JavaScript

¿Cuál es la diferencia entre pruebas unitarias, de integración y E2E

A una prueba unitaria verifica una pequeña pieza de lógica de manera aislada prueba de integración verifica si algunos componentes o servicios funcionan correctamente. Un prueba de final a final ejerce un recorrido de usuario a través de la aplicación en ejecución.

Utilice las pruebas unitarias para obtener confianza rápida en las reglas comerciales. Utilice las pruebas de integración para junturas como almacenamiento, envolturas de plugins y IPC. Utilice las pruebas E2E con moderación para los flujos de trabajo que dañarían seriamente si se rompieran.

¿Debemos aspirar a una cobertura completa

No. La cobertura completa puede empujar a los equipos hacia pruebas de baja valor.

La cobertura es útil cuando revela riesgos code que nadie ha ejercitado. No es útil cuando los ingenieros agregan afirmaciones superficiales solo para satisfacer una pantalla de control. Si su conjunto es frágil, más cobertura no lo salvará.

¿Cómo agregamos pruebas a un códigobase existente

Comience donde ya suceden cambios. No congele al equipo y anuncie una gran reescritura de la estrategia de pruebas.

Una secuencia práctica se parece a esto:

  • Proteja los code activos primero al agregar pruebas a los módulos que tocas durante el trabajo de características o correcciones de errores
  • Extraer lógica pura de archivos difíciles de probar para que las reglas comerciales puedan ser probadas sin ruido del marco o del tiempo de ejecución
  • Agregar envolturas de costura alrededor de plugins nativos, clientes de red, llamadas al sistema de archivos y IPC de Electron
  • Rechazar patrones frágiles cuando se introducen mocks. La guía de prácticas de prueba de JavaScript es especialmente útil aquí porque destaca el problema a menudo pasado por alto de sobre-mockeo y las pruebas frágiles que siguen

El objetivo no es la completitud inmediata. Es una mejora constante en los lugares donde las regresiones cuestan al equipo más


Si tu equipo envía Capacitor o Electron aplicaciones y requiere un proceso de liberación más limpio alrededor de los cambios de JavaScript, Capgo es una opción para considerar. Proporciona actualizaciones en vivo para aplicaciones de CapacitorJS y Electron, con controles de despliegue y observabilidad, por lo que los equipos pueden combinar pruebas unitarias sólidas con un camino más seguro para enviar cambios en el paquete web sin tener que esperar a la revisión de la tienda para cada corrección.

Actualizaciones en vivo para aplicaciones Capacitor

Cuando un error en la capa web está activo, envíe la corrección a través de Capgo en lugar de esperar días por la aprobación de la tienda de aplicaciones. Los usuarios obtienen la actualización en segundo plano mientras los cambios nativos siguen en el camino de revisión normal.

Comienza ahora

Últimas noticias de nuestro Blog

Capgo le da las mejores perspectivas que necesita para crear una aplicación móvil verdaderamente profesional.