Saltar al contenido principal

Pruebas Unitarias de JavaScript: Guía Integral 2026

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

Martin Donadieu

Martin Donadieu

Gerente de Contenido

Pruebas Unitarias de JavaScript: Guía Integral 2026

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

Que empeora en Capacitor y Electron aplicaciones. Una característica simple puede interactuar con 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 falla.

Las pruebas unitarias del JavaScript no comienzan con la sintaxis de los matchers inteligentes. Comienza con un límite disciplinado: 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

Elección de tu marco de pruebas de JavaScript

Un proyecto de JavaScript profesional necesita un verdadero ejecutor de pruebas. Los scripts ad hoc y los controles de consola manuales no escalan cuando varios ingenieros tocan el mismo códigobase. Necesitas descubrimiento de pruebas, afirmaciones, manejo de sincronización asíncrona, 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 destacados repetidamente como los marcos principales, con Jest a menudo destacado 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 populares frameworks de pruebas de JavaScript, 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
  • Afirmaciones con comparadores legibles
  • Hooks para la configuración y el desmantelamiento
  • 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 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.

Jest es la opción todo en uno. Lleva la mayoría de lo que los 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ística Jest Mocha
Complejidad de configuración Menor para la mayoría de los equipos Mayor porque normalmente agregas bibliotecas de afirmaciones y simulación
Afirmaciones Incorporadas Normalmente se combina con otra biblioteca
Simulación Integrado por defecto Normalmente se combina con otra biblioteca
Pruebas asíncronas Integrado por defecto y directo Soportado, pero depende más de la configuración circundante
Flujo de cobertura Comúnmente integrado en el mismo conjunto de herramientas A menudo más ensamblado
Mejor ajuste Nuevos proyectos, equipos que quieren consistencia Legados, equipos que quieren control modular

Regla práctica: Si su equipo tiene que preguntar cuál es la biblioteca de afirmación y cuál es la biblioteca de simulación que deben pair con el ejecutor, probablemente querrá 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 ya tenga razones fuertes 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 una suite robusta desde cero, Jest suele eliminar más fricciones de las que crea.

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

Configuración del proyecto y tu primer test

Una configuración de prueba limpia debería ser aburrida. Si agregar la primera prueba parece complicado, el conjunto de pruebas probablemente no permanecerá 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

Comience con un proyecto de JavaScript que ya tiene un package.json. Luego agregue Jest como una dependencia de desarrollo y configure un script de prueba.

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

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

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

Escriba la prueba antes de la code

El patrón de prueba primero no es solo una preferencia personal. La guía de JavaScript del Bureau de Protección Financiera del Consumidor de los EE. UU. recomienda explícitamente escribir la prueba primero, organizando pruebas con describe y it, y configurando comprobaciones alrededor de expect(...) declaraciones en su orientación de pruebas unitarias de JavaScript.

Eso importa porque los cambios de prueba primero cambian cómo diseñan code. Las funciones tienden a volverse más pequeñas, las dependencias se vuelven más visibles, y los efectos laterales dejan de filtrarse en la lógica que debería permanecer pura.

Aquí está 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);
  });
});

Utilice Arrange Act Assert cada vez

El patrón de Arrange, Act, Assert mantiene las pruebas legibles, incluso cuando crecen más complejas.

  1. Arrange la entrada y cualquier configuración necesaria.
  2. Actuar realizar una llamada a la función.
  3. Assertar evaluar el resultado.

Aplicado a un asistente 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 es más importante 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 Asincronía 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.

Es ahí donde ayuda el mocking. Te da control sobre la frontera para que la prueba pueda centrarse en la toma de decisiones de tu code.

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

Simulacros de fronteras, no todo

La guía de pruebas mantenibles enfatiza cobertura de un comportamiento por prueba y una sola afirmación fuerte por prueba, y también advierte que el uso excesivo de simulacros 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 a menudo comienzan 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 incorrecto para una prueba pesada en simulacros:

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

Mejor objetivo:

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

Un mejor patrón 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, 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 ipcRendererel acceso a archivos, o las integraciones de shell 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 aplicaciones Capacitor, Capgo tiene una guía relevante sobre la prueba de actualizaciones OTA de Capacitor con escenarios de simulación.

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

Pruebas de flujo asíncrono sin inestabilidad

Usar async/await en las pruebas cuando el code bajo prueba devuelve una promesa. Es más claro que los patrones pesados en callbacks y 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 pruebe 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');
});

Pruebe tanto el camino feliz como el camino feo. En producción, el camino feo es 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.

Usar la división de pruebas como un presupuesto

Una guía práctica recomienda una 70/20/10 división en pruebas unitarias, pruebas de integración y pruebas de fin de ciclo, con pruebas unitarias que proporcionan la retroalimentación más rápida y las fallas más estables. La misma guía dice que un conjunto de pruebas unitarias completo debería terminar idealmente 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 presupuestación, no una religión. Si la mayor parte de su esfuerzo se dirige a pruebas de fin a fin, su equipo esperará demasiado tiempo para recibir retroalimentación. Si todo es solo unitario, se perderán las verdaderas fronteras del sistema..

Para una aplicación __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 Pruebas de integración
  • para adaptadores de almacenamiento, envolturas de plugins y contratos de IPC targetLanguage
  • E2E pruebas para un par de 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 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 code con entrada pesada como formularios, analizador de sintaxis, lógica de fechas y verificaciones de permisos. Si su equipo está ajustando la calidad alrededor de la validación de la interfaz de usuario, esta guía sobre dominio de 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 permitir que refactores internos sin reescribir 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.

Los casos de uso que se sostienen bien:

  • Condiciones de límite como la entrada vacía, valores nulos, tipos inválidos y cadenas de texto demasiado grandes
  • Resultados del dominio como “se deniegan devoluciones por falta de permiso”
  • Transiciones de estado como “actualiza la marca como pendiente después de validar los metadatos de descarga”

Casos de uso que a menudo se descomponen:

  • inspeccionar llamadas de ayuda internas
  • asegurar 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 aseguramiento de calidad de aplicaciones es útil porque conecta el trabajo de pruebas con el pipeline de liberación más amplio.

Pruebas para CI, Capacitor, y aplicaciones de Electron

Un test que solo se ejecuta en la máquina de un desarrollador no es una red de seguridad. Es una costumbre local.

La CI convierte las pruebas unitarias en infraestructura de equipo. Cada empuje, 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.

Haga que la CI sea 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 al desarrollo local cuando sea posible.

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

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

Eso es suficiente para capturar importaciones rotas, afirmaciones fallidas y suposiciones de plataforma accidentales antes de que lleguen a la principal.

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

Pruebas de interacción de plugin de Capacitor

La forma incorrecta de probar unidades de Capacitor code es tirar plugins nativos directamente en cada servicio. Eso acopla su conjunto de pruebas con 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, promps biométricos, registro de tokens de notificación y estado de red. Mantenga las llamadas de plugins en los adaptadores. Pruebe la lógica de la aplicación contra interfaces que controla.

Pruebas de Electron main renderer y IPC code

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

Una configuración confiable separa generalmente:

  • Pruebas unitarias de renderizado para modelos de vista, estado, formateo y lógica de negocio del lado de 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 más tarde la implementación interna de un helper a otro, esta prueba sigue siendo válida porque verifica el comportamiento que importa. Eso 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 e integración y E2E

A prueba unitaria verifica una pequeña pieza de lógica de manera aislada. Una prueba de integración verifica si un par de componentes o servicios funcionan correctamente juntos. Un prueba de rendimiento final Las pruebas de rendimiento final ejercitan un recorrido del usuario a través de la aplicación en ejecución.

Use pruebas unitarias para una confianza rápida en las reglas comerciales. Use pruebas de integración para junturas como almacenamiento, envolturas de plugins y IPC. Use pruebas E2E con moderación para los flujos de trabajo que serían muy perjudiciales 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

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

Una secuencia práctica se parece a esto:

  • Protege los code activos primero al agregar pruebas a los módulos que tocas durante el trabajo de características o correcciones de errores
  • Extrae la lógica pura desde archivos difíciles de probar para que las reglas comerciales puedan ser probadas sin ruido de marco o 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 su equipo envía Capacitor o Electron las aplicaciones y necesita 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 de paquetes web sin tener que esperar a la revisión de la tienda para cada corrección.

Actualizaciones en vivo para aplicaciones Capacitor

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

Inicie ahora

Últimas noticias de nuestro Blog

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