Skip to content

Ejecutor de pruebas

[Historial]

VersiónCambios
v20.0.0El ejecutor de pruebas ahora es estable.
v18.0.0, v16.17.0Añadido en: v18.0.0, v16.17.0

[Estable: 2 - Estable]

Estable: 2 Estabilidad: 2 - Estable

Código fuente: lib/test.js

El módulo node:test facilita la creación de pruebas de JavaScript. Para acceder a él:

js
import test from 'node:test'
js
const test = require('node:test')

Este módulo solo está disponible bajo el esquema node:.

Las pruebas creadas a través del módulo test consisten en una única función que se procesa de una de tres formas:

El siguiente ejemplo ilustra cómo se escriben las pruebas utilizando el módulo test.

js
test('prueba síncrona que pasa', t => {
  // Esta prueba pasa porque no lanza una excepción.
  assert.strictEqual(1, 1)
})

test('prueba síncrona que falla', t => {
  // Esta prueba falla porque lanza una excepción.
  assert.strictEqual(1, 2)
})

test('prueba asíncrona que pasa', async t => {
  // Esta prueba pasa porque la Promesa devuelta por la función async
  // se resuelve y no se rechaza.
  assert.strictEqual(1, 1)
})

test('prueba asíncrona que falla', async t => {
  // Esta prueba falla porque la Promesa devuelta por la función async
  // se rechaza.
  assert.strictEqual(1, 2)
})

test('prueba que falla usando Promesas', t => {
  // Las Promesas también se pueden usar directamente.
  return new Promise((resolve, reject) => {
    setImmediate(() => {
      reject(new Error('esto hará que la prueba falle'))
    })
  })
})

test('prueba de callback que pasa', (t, done) => {
  // done() es la función de callback. Cuando se ejecuta setImmediate(), invoca
  // done() sin argumentos.
  setImmediate(done)
})

test('prueba de callback que falla', (t, done) => {
  // Cuando se ejecuta setImmediate(), done() se invoca con un objeto Error y
  // la prueba falla.
  setImmediate(() => {
    done(new Error('fallo del callback'))
  })
})

Si alguna prueba falla, el código de salida del proceso se establece en 1.

Subpruebas

El método test() del contexto de prueba permite crear subpruebas. Esto le permite estructurar sus pruebas de manera jerárquica, donde puede crear pruebas anidadas dentro de una prueba más grande. Este método se comporta de manera idéntica a la función test() de nivel superior. El siguiente ejemplo demuestra la creación de una prueba de nivel superior con dos subpruebas.

js
test('prueba de nivel superior', async t => {
  await t.test('subprueba 1', t => {
    assert.strictEqual(1, 1)
  })

  await t.test('subprueba 2', t => {
    assert.strictEqual(2, 2)
  })
})

En este ejemplo, se usa await para asegurarse de que ambas subpruebas se hayan completado. Esto es necesario porque las pruebas no esperan a que sus subpruebas se completen, a diferencia de las pruebas creadas dentro de los conjuntos. Cualquier subprueba que aún esté pendiente cuando finaliza su padre se cancela y se trata como un fallo. Cualquier fallo de subprueba hace que la prueba principal falle.

Omitir pruebas

Las pruebas individuales se pueden omitir pasando la opción skip a la prueba, o llamando al método skip() del contexto de prueba como se muestra en el siguiente ejemplo.

js
// Se utiliza la opción skip, pero no se proporciona ningún mensaje.
test('opción skip', { skip: true }, t => {
  // Este código nunca se ejecuta.
})

// Se utiliza la opción skip y se proporciona un mensaje.
test('opción skip con mensaje', { skip: 'esto se omite' }, t => {
  // Este código nunca se ejecuta.
})

test('método skip()', t => {
  // Asegúrese de regresar aquí también si la prueba contiene lógica adicional.
  t.skip()
})

test('método skip() con mensaje', t => {
  // Asegúrese de regresar aquí también si la prueba contiene lógica adicional.
  t.skip('esto se omite')
})

Pruebas TODO

Las pruebas individuales se pueden marcar como inestables o incompletas pasando la opción todo a la prueba, o llamando al método todo() del contexto de la prueba, como se muestra en el siguiente ejemplo. Estas pruebas representan una implementación pendiente o un error que debe corregirse. Las pruebas TODO se ejecutan, pero no se tratan como fallos de prueba y, por lo tanto, no afectan al código de salida del proceso. Si una prueba se marca como TODO y omitida, la opción TODO se ignora.

js
// Se utiliza la opción todo, pero no se proporciona ningún mensaje.
test('opción todo', { todo: true }, t => {
  // Este código se ejecuta, pero no se trata como un fallo.
  throw new Error('esto no hace que falle la prueba')
})

// Se utiliza la opción todo y se proporciona un mensaje.
test('opción todo con mensaje', { todo: 'esta es una prueba todo' }, t => {
  // Este código se ejecuta.
})

test('método todo()', t => {
  t.todo()
})

test('método todo() con mensaje', t => {
  t.todo('esta es una prueba todo y no se trata como un fallo')
  throw new Error('esto no hace que falle la prueba')
})

Alias de describe() y it()

Las suites y las pruebas también se pueden escribir usando las funciones describe() e it(). describe() es un alias para suite(), e it() es un alias para test().

js
describe('Una cosa', () => {
  it('debería funcionar', () => {
    assert.strictEqual(1, 1)
  })

  it('debería estar bien', () => {
    assert.strictEqual(2, 2)
  })

  describe('una cosa anidada', () => {
    it('debería funcionar', () => {
      assert.strictEqual(3, 3)
    })
  })
})

describe() e it() se importan del módulo node:test.

js
import { describe, it } from 'node:test'
js
const { describe, it } = require('node:test')

Pruebas only

Si Node.js se inicia con la opción de línea de comandos --test-only, o la aislamiento de pruebas está deshabilitada, es posible omitir todas las pruebas, excepto un subconjunto seleccionado, pasando la opción only a las pruebas que se deben ejecutar. Cuando se establece una prueba con la opción only, también se ejecutan todas las subpruebas. Si una suite tiene establecida la opción only, se ejecutan todas las pruebas dentro de la suite, a menos que tenga descendientes con la opción only establecida, en cuyo caso solo se ejecutan esas pruebas.

Al usar subpruebas dentro de un test()/it(), es necesario marcar todas las pruebas ancestras con la opción only para ejecutar solo un subconjunto seleccionado de pruebas.

El método runOnly() del contexto de la prueba se puede usar para implementar el mismo comportamiento a nivel de subprueba. Las pruebas que no se ejecutan se omiten de la salida del ejecutor de pruebas.

js
// Se asume que Node.js se ejecuta con la opción de línea de comandos --test-only.
// La opción 'only' de la suite está establecida, por lo que estas pruebas se ejecutan.
test('esta prueba se ejecuta', { only: true }, async t => {
  // Dentro de esta prueba, todas las subpruebas se ejecutan de forma predeterminada.
  await t.test('subprueba en ejecución')

  // El contexto de la prueba se puede actualizar para ejecutar subpruebas con la opción 'only'.
  t.runOnly(true)
  await t.test('esta subprueba ahora se omite')
  await t.test('esta subprueba se ejecuta', { only: true })

  // Cambia el contexto de nuevo para ejecutar todas las pruebas.
  t.runOnly(false)
  await t.test('esta subprueba ahora se ejecuta')

  // No ejecutar explícitamente estas pruebas.
  await t.test('subprueba omitida 3', { only: false })
  await t.test('subprueba omitida 4', { skip: true })
})

// La opción 'only' no está establecida, por lo que esta prueba se omite.
test('esta prueba no se ejecuta', () => {
  // Este código no se ejecuta.
  throw new Error('falló')
})

describe('una suite', () => {
  // La opción 'only' está establecida, por lo que esta prueba se ejecuta.
  it('esta prueba se ejecuta', { only: true }, () => {
    // Este código se ejecuta.
  })

  it('esta prueba no se ejecuta', () => {
    // Este código no se ejecuta.
    throw new Error('falló')
  })
})

describe.only('una suite', () => {
  // La opción 'only' está establecida, por lo que esta prueba se ejecuta.
  it('esta prueba se ejecuta', () => {
    // Este código se ejecuta.
  })

  it('esta prueba se ejecuta', () => {
    // Este código se ejecuta.
  })
})

Filtrado de pruebas por nombre

La opción de línea de comandos --test-name-pattern se puede utilizar para ejecutar solo las pruebas cuyo nombre coincida con el patrón proporcionado, y la opción --test-skip-pattern se puede utilizar para omitir las pruebas cuyo nombre coincida con el patrón proporcionado. Los patrones de nombres de prueba se interpretan como expresiones regulares de JavaScript. Las opciones --test-name-pattern y --test-skip-pattern se pueden especificar varias veces para ejecutar pruebas anidadas. Para cada prueba que se ejecuta, también se ejecutan los ganchos de prueba correspondientes, como beforeEach(). Las pruebas que no se ejecutan se omiten de la salida del ejecutor de pruebas.

Dado el siguiente archivo de prueba, iniciar Node.js con la opción --test-name-pattern="test [1-3]" haría que el ejecutor de pruebas ejecutara test 1, test 2 y test 3. Si test 1 no coincidiera con el patrón de nombre de prueba, sus subpruebas no se ejecutarían, a pesar de coincidir con el patrón. El mismo conjunto de pruebas también podría ejecutarse pasando --test-name-pattern varias veces (por ejemplo, --test-name-pattern="test 1", --test-name-pattern="test 2", etc.).

js
test('test 1', async t => {
  await t.test('test 2')
  await t.test('test 3')
})

test('Test 4', async t => {
  await t.test('Test 5')
  await t.test('test 6')
})

Los patrones de nombres de prueba también se pueden especificar utilizando literales de expresiones regulares. Esto permite utilizar las banderas de expresiones regulares. En el ejemplo anterior, iniciar Node.js con --test-name-pattern="/test [4-5]/i" (o --test-skip-pattern="/test [4-5]/i") coincidiría con Test 4 y Test 5 porque el patrón no distingue entre mayúsculas y minúsculas.

Para hacer coincidir una sola prueba con un patrón, puede prefijarla con todos los nombres de prueba de sus ancestros separados por un espacio, para asegurar que sea única. Por ejemplo, dado el siguiente archivo de prueba:

js
describe('test 1', t => {
  it('some test')
})

describe('test 2', t => {
  it('some test')
})

Iniciar Node.js con --test-name-pattern="test 1 some test" solo coincidiría con some test en test 1.

Los patrones de nombres de prueba no cambian el conjunto de archivos que ejecuta el ejecutor de pruebas.

Si se proporcionan tanto --test-name-pattern como --test-skip-pattern, las pruebas deben satisfacer ambos requisitos para ser ejecutadas.

Actividad asíncrona extraña

Una vez que una función de prueba termina de ejecutarse, los resultados se reportan lo más rápido posible manteniendo el orden de las pruebas. Sin embargo, es posible que la función de prueba genere actividad asíncrona que sobreviva a la propia prueba. El ejecutor de pruebas maneja este tipo de actividad, pero no retrasa el informe de los resultados de las pruebas para acomodarla.

En el siguiente ejemplo, una prueba finaliza con dos operaciones setImmediate() aún pendientes. La primera setImmediate() intenta crear una nueva subprueba. Debido a que la prueba principal ya ha finalizado y ha emitido sus resultados, la nueva subprueba se marca inmediatamente como fallida y se informa posteriormente al <TestsStream>.

La segunda setImmediate() crea un evento uncaughtException. Los eventos uncaughtException y unhandledRejection que se originan a partir de una prueba completada son marcados como fallidos por el módulo test y se informan como advertencias de diagnóstico en el nivel superior por el <TestsStream>.

js
test('una prueba que crea actividad asíncrona', t => {
  setImmediate(() => {
    t.test('subprueba que se crea demasiado tarde', t => {
      throw new Error('error1')
    })
  })

  setImmediate(() => {
    throw new Error('error2')
  })

  // La prueba termina después de esta línea.
})

Modo de Observación

Añadido en: v19.2.0, v18.13.0

[Estable: 1 - Experimental]

Estable: 1 Estabilidad: 1 - Experimental

El ejecutor de pruebas de Node.js admite la ejecución en modo de observación pasando la bandera --watch:

bash
node --test --watch

En modo de observación, el ejecutor de pruebas observará los cambios en los archivos de prueba y sus dependencias. Cuando se detecta un cambio, el ejecutor de pruebas volverá a ejecutar las pruebas afectadas por el cambio. El ejecutor de pruebas continuará ejecutándose hasta que se termine el proceso.

Ejecución de pruebas desde la línea de comandos

El ejecutor de pruebas de Node.js se puede invocar desde la línea de comandos pasando la bandera --test:

bash
node --test

De forma predeterminada, Node.js ejecutará todos los archivos que coincidan con estos patrones:

  • **/*.test.{cjs,mjs,js}
  • **/*-test.{cjs,mjs,js}
  • **/*_test.{cjs,mjs,js}
  • **/test-*.{cjs,mjs,js}
  • **/test.{cjs,mjs,js}
  • **/test/**/*.{cjs,mjs,js}

Cuando se proporciona --experimental-strip-types, se coinciden los siguientes patrones adicionales:

  • **/*.test.{cts,mts,ts}
  • **/*-test.{cts,mts,ts}
  • **/*_test.{cts,mts,ts}
  • **/test-*.{cts,mts,ts}
  • **/test.{cts,mts,ts}
  • **/test/**/*.{cts,mts,ts}

Alternativamente, se pueden proporcionar uno o más patrones glob como el argumento(s) final(es) al comando de Node.js, como se muestra a continuación. Los patrones glob siguen el comportamiento de glob(7). Los patrones glob deben estar encerrados entre comillas dobles en la línea de comandos para evitar la expansión del shell, lo que puede reducir la portabilidad entre sistemas.

bash
node --test "**/*.test.js" "**/*.spec.js"

Los archivos coincidentes se ejecutan como archivos de prueba. Se puede encontrar más información sobre la ejecución de archivos de prueba en la sección modelo de ejecución del ejecutor de pruebas.

Modelo de ejecución del ejecutor de pruebas

Cuando el aislamiento de pruebas a nivel de proceso está habilitado, cada archivo de prueba coincidente se ejecuta en un proceso hijo separado. El número máximo de procesos hijos que se ejecutan en un momento dado está controlado por el indicador --test-concurrency. Si el proceso hijo finaliza con un código de salida de 0, se considera que la prueba ha pasado. De lo contrario, se considera que la prueba ha fallado. Los archivos de prueba deben ser ejecutables por Node.js, pero no es necesario que utilicen el módulo node:test internamente.

Cada archivo de prueba se ejecuta como si fuera un script normal. Es decir, si el propio archivo de prueba utiliza node:test para definir las pruebas, todas esas pruebas se ejecutarán dentro de un único hilo de aplicación, independientemente del valor de la opción concurrency de test().

Cuando el aislamiento de pruebas a nivel de proceso está deshabilitado, cada archivo de prueba coincidente se importa al proceso del ejecutor de pruebas. Una vez que se han cargado todos los archivos de prueba, las pruebas de nivel superior se ejecutan con una concurrencia de uno. Debido a que todos los archivos de prueba se ejecutan dentro del mismo contexto, es posible que las pruebas interactúen entre sí de formas que no son posibles cuando el aislamiento está habilitado. Por ejemplo, si una prueba depende de un estado global, es posible que ese estado sea modificado por una prueba que se origine en otro archivo.

Recopilación de cobertura de código

[Estable: 1 - Experimental]

Estable: 1 Estabilidad: 1 - Experimental

Cuando Node.js se inicia con el indicador de línea de comandos --experimental-test-coverage, se recopila la cobertura de código y se informan las estadísticas una vez que se han completado todas las pruebas. Si la variable de entorno NODE_V8_COVERAGE se utiliza para especificar un directorio de cobertura de código, los archivos de cobertura V8 generados se escriben en ese directorio. Los módulos principales de Node.js y los archivos dentro de los directorios node_modules/ no se incluyen, de forma predeterminada, en el informe de cobertura. Sin embargo, se pueden incluir explícitamente a través del indicador --test-coverage-include. De forma predeterminada, todos los archivos de prueba coincidentes se excluyen del informe de cobertura. Las exclusiones se pueden anular utilizando el indicador --test-coverage-exclude. Si la cobertura está habilitada, el informe de cobertura se envía a cualquier informador de pruebas a través del evento 'test:coverage'.

La cobertura se puede deshabilitar en una serie de líneas utilizando la siguiente sintaxis de comentario:

js
/* node:coverage disable */
if (anAlwaysFalseCondition) {
  // El código en esta rama nunca se ejecutará, pero las líneas se ignoran a
  // efectos de cobertura. Todas las líneas que siguen al comentario 'disable' se ignoran
  // hasta que se encuentra un comentario 'enable' correspondiente.
  console.log('esto nunca se ejecuta')
}
/* node:coverage enable */

La cobertura también se puede deshabilitar para un número específico de líneas. Después del número especificado de líneas, la cobertura se volverá a habilitar automáticamente. Si el número de líneas no se proporciona explícitamente, se ignora una sola línea.

js
/* node:coverage ignore next */
if (anAlwaysFalseCondition) {
  console.log('esto nunca se ejecuta')
}

/* node:coverage ignore next 3 */
if (anAlwaysFalseCondition) {
  console.log('esto nunca se ejecuta')
}

Informes de cobertura

Los informes tap y spec imprimirán un resumen de las estadísticas de cobertura. También hay un informe lcov que generará un archivo lcov que puede utilizarse como informe de cobertura detallado.

bash
node --test --experimental-test-coverage --test-reporter=lcov --test-reporter-destination=lcov.info
  • Este informe no reporta ningún resultado de prueba.
  • Lo ideal sería utilizar este informe junto con otro.

Mocking

El módulo node:test admite el mocking durante las pruebas a través de un objeto mock de nivel superior. El siguiente ejemplo crea un spy en una función que suma dos números. A continuación, se utiliza el spy para afirmar que la función se llamó como se esperaba.

js
import assert from 'node:assert'
import { mock, test } from 'node:test'

test('spies on a function', () => {
  const sum = mock.fn((a, b) => {
    return a + b
  })

  assert.strictEqual(sum.mock.callCount(), 0)
  assert.strictEqual(sum(3, 4), 7)
  assert.strictEqual(sum.mock.callCount(), 1)

  const call = sum.mock.calls[0]
  assert.deepStrictEqual(call.arguments, [3, 4])
  assert.strictEqual(call.result, 7)
  assert.strictEqual(call.error, undefined)

  // Reset the globally tracked mocks.
  mock.reset()
})
js
'use strict'
const assert = require('node:assert')
const { mock, test } = require('node:test')

test('spies on a function', () => {
  const sum = mock.fn((a, b) => {
    return a + b
  })

  assert.strictEqual(sum.mock.callCount(), 0)
  assert.strictEqual(sum(3, 4), 7)
  assert.strictEqual(sum.mock.callCount(), 1)

  const call = sum.mock.calls[0]
  assert.deepStrictEqual(call.arguments, [3, 4])
  assert.strictEqual(call.result, 7)
  assert.strictEqual(call.error, undefined)

  // Reset the globally tracked mocks.
  mock.reset()
})

La misma funcionalidad de mocking también se expone en el objeto TestContext de cada prueba. El siguiente ejemplo crea un spy en un método de objeto utilizando la API expuesta en TestContext. La ventaja de hacer mocking a través del contexto de prueba es que el ejecutor de pruebas restaurará automáticamente toda la funcionalidad mocked una vez que finalice la prueba.

js
test('spies on an object method', t => {
  const number = {
    value: 5,
    add(a) {
      return this.value + a
    },
  }

  t.mock.method(number, 'add')
  assert.strictEqual(number.add.mock.callCount(), 0)
  assert.strictEqual(number.add(3), 8)
  assert.strictEqual(number.add.mock.callCount(), 1)

  const call = number.add.mock.calls[0]

  assert.deepStrictEqual(call.arguments, [3])
  assert.strictEqual(call.result, 8)
  assert.strictEqual(call.target, undefined)
  assert.strictEqual(call.this, number)
})

Temporizadores

La simulación de temporizadores es una técnica comúnmente utilizada en las pruebas de software para simular y controlar el comportamiento de los temporizadores, como setInterval y setTimeout, sin tener que esperar realmente los intervalos de tiempo especificados.

Consulte la clase MockTimers para obtener una lista completa de métodos y funciones.

Esto permite a los desarrolladores escribir pruebas más confiables y predecibles para la funcionalidad dependiente del tiempo.

El ejemplo siguiente muestra cómo simular setTimeout. Al usar .enable({ apis: ['setTimeout'] }); simulará las funciones setTimeout en los módulos node:timers y node:timers/promises, así como desde el contexto global de Node.js.

Nota: La desestructuración de funciones como import { setTimeout } from 'node:timers' no es compatible actualmente con esta API.

js
import assert from 'node:assert'
import { mock, test } from 'node:test'

test('simula setTimeout para que se ejecute sincrónicamente sin tener que esperar realmente', () => {
  const fn = mock.fn()

  // Opcionalmente, elija qué simular
  mock.timers.enable({ apis: ['setTimeout'] })
  setTimeout(fn, 9999)
  assert.strictEqual(fn.mock.callCount(), 0)

  // Avanzar en el tiempo
  mock.timers.tick(9999)
  assert.strictEqual(fn.mock.callCount(), 1)

  // Restablecer las simulaciones rastreadas globalmente.
  mock.timers.reset()

  // Si llama a restablecer la instancia de simulación, también restablecerá la instancia de temporizadores
  mock.reset()
})
js
const assert = require('node:assert')
const { mock, test } = require('node:test')

test('simula setTimeout para que se ejecute sincrónicamente sin tener que esperar realmente', () => {
  const fn = mock.fn()

  // Opcionalmente, elija qué simular
  mock.timers.enable({ apis: ['setTimeout'] })
  setTimeout(fn, 9999)
  assert.strictEqual(fn.mock.callCount(), 0)

  // Avanzar en el tiempo
  mock.timers.tick(9999)
  assert.strictEqual(fn.mock.callCount(), 1)

  // Restablecer las simulaciones rastreadas globalmente.
  mock.timers.reset()

  // Si llama a restablecer la instancia de simulación, también restablecerá la instancia de temporizadores
  mock.reset()
})

La misma funcionalidad de simulación también se expone en la propiedad mock del objeto TestContext de cada prueba. El beneficio de la simulación a través del contexto de prueba es que el ejecutor de pruebas restaurará automáticamente toda la funcionalidad de temporizadores simulados una vez que finalice la prueba.

js
import assert from 'node:assert'
import { test } from 'node:test'

test('simula setTimeout para que se ejecute sincrónicamente sin tener que esperar realmente', context => {
  const fn = context.mock.fn()

  // Opcionalmente, elija qué simular
  context.mock.timers.enable({ apis: ['setTimeout'] })
  setTimeout(fn, 9999)
  assert.strictEqual(fn.mock.callCount(), 0)

  // Avanzar en el tiempo
  context.mock.timers.tick(9999)
  assert.strictEqual(fn.mock.callCount(), 1)
})
js
const assert = require('node:assert')
const { test } = require('node:test')

test('simula setTimeout para que se ejecute sincrónicamente sin tener que esperar realmente', context => {
  const fn = context.mock.fn()

  // Opcionalmente, elija qué simular
  context.mock.timers.enable({ apis: ['setTimeout'] })
  setTimeout(fn, 9999)
  assert.strictEqual(fn.mock.callCount(), 0)

  // Avanzar en el tiempo
  context.mock.timers.tick(9999)
  assert.strictEqual(fn.mock.callCount(), 1)
})

Fechas

La API de simulacros de temporizadores también permite simular el objeto Date. Esta es una función útil para probar la funcionalidad dependiente del tiempo o para simular funciones internas de calendario como Date.now().

La implementación de fechas también forma parte de la clase MockTimers. Consulte esta clase para obtener una lista completa de métodos y funciones.

Nota: Las fechas y los temporizadores son dependientes cuando se simulan juntos. Esto significa que si tiene simulado tanto Date como setTimeout, avanzar en el tiempo también avanzará la fecha simulada, ya que simulan un único reloj interno.

El siguiente ejemplo muestra cómo simular el objeto Date y obtener el valor actual de Date.now().

js
import assert from 'node:assert'
import { test } from 'node:test'

test('simula el objeto Date', context => {
  // Opcionalmente, elija qué simular
  context.mock.timers.enable({ apis: ['Date'] })
  // Si no se especifica, la fecha inicial se basará en 0 en la época de UNIX
  assert.strictEqual(Date.now(), 0)

  // Avanzar en el tiempo también avanzará la fecha
  context.mock.timers.tick(9999)
  assert.strictEqual(Date.now(), 9999)
})
js
const assert = require('node:assert')
const { test } = require('node:test')

test('simula el objeto Date', context => {
  // Opcionalmente, elija qué simular
  context.mock.timers.enable({ apis: ['Date'] })
  // Si no se especifica, la fecha inicial se basará en 0 en la época de UNIX
  assert.strictEqual(Date.now(), 0)

  // Avanzar en el tiempo también avanzará la fecha
  context.mock.timers.tick(9999)
  assert.strictEqual(Date.now(), 9999)
})

Si no se establece ninguna época inicial, la fecha inicial se basará en 0 en la época de Unix. Esto es el 1 de enero de 1970, 00:00:00 UTC. Puede establecer una fecha inicial pasando una propiedad now al método .enable(). Este valor se utilizará como la fecha inicial para el objeto Date simulado. Puede ser un entero positivo u otro objeto Date.

js
import assert from 'node:assert'
import { test } from 'node:test'

test('simula el objeto Date con tiempo inicial', context => {
  // Opcionalmente, elija qué simular
  context.mock.timers.enable({ apis: ['Date'], now: 100 })
  assert.strictEqual(Date.now(), 100)

  // Avanzar en el tiempo también avanzará la fecha
  context.mock.timers.tick(200)
  assert.strictEqual(Date.now(), 300)
})
js
const assert = require('node:assert')
const { test } = require('node:test')

test('simula el objeto Date con tiempo inicial', context => {
  // Opcionalmente, elija qué simular
  context.mock.timers.enable({ apis: ['Date'], now: 100 })
  assert.strictEqual(Date.now(), 100)

  // Avanzar en el tiempo también avanzará la fecha
  context.mock.timers.tick(200)
  assert.strictEqual(Date.now(), 300)
})

Puede usar el método .setTime() para mover manualmente la fecha simulada a otra hora. Este método solo acepta un entero positivo.

Nota: Este método ejecutará cualquier temporizador simulado que esté en el pasado desde la nueva hora.

En el siguiente ejemplo, estamos estableciendo una nueva hora para la fecha simulada.

js
import assert from 'node:assert'
import { test } from 'node:test'

test('establece la hora de un objeto de fecha', context => {
  // Opcionalmente, elija qué simular
  context.mock.timers.enable({ apis: ['Date'], now: 100 })
  assert.strictEqual(Date.now(), 100)

  // Avanzar en el tiempo también avanzará la fecha
  context.mock.timers.setTime(1000)
  context.mock.timers.tick(200)
  assert.strictEqual(Date.now(), 1200)
})
js
const assert = require('node:assert')
const { test } = require('node:test')

test('establece la hora de un objeto de fecha', context => {
  // Opcionalmente, elija qué simular
  context.mock.timers.enable({ apis: ['Date'], now: 100 })
  assert.strictEqual(Date.now(), 100)

  // Avanzar en el tiempo también avanzará la fecha
  context.mock.timers.setTime(1000)
  context.mock.timers.tick(200)
  assert.strictEqual(Date.now(), 1200)
})

Si tiene algún temporizador configurado para ejecutarse en el pasado, se ejecutará como si se hubiera llamado al método .tick(). Esto es útil si desea probar la funcionalidad dependiente del tiempo que ya está en el pasado.

js
import assert from 'node:assert'
import { test } from 'node:test'

test('ejecuta temporizadores mientras setTime pasa ticks', context => {
  // Opcionalmente, elija qué simular
  context.mock.timers.enable({ apis: ['setTimeout', 'Date'] })
  const fn = context.mock.fn()
  setTimeout(fn, 1000)

  context.mock.timers.setTime(800)
  // El temporizador no se ejecuta ya que aún no se ha alcanzado la hora
  assert.strictEqual(fn.mock.callCount(), 0)
  assert.strictEqual(Date.now(), 800)

  context.mock.timers.setTime(1200)
  // El temporizador se ejecuta ya que ahora se ha alcanzado la hora
  assert.strictEqual(fn.mock.callCount(), 1)
  assert.strictEqual(Date.now(), 1200)
})
js
const assert = require('node:assert')
const { test } = require('node:test')

test('ejecuta temporizadores mientras setTime pasa ticks', context => {
  // Opcionalmente, elija qué simular
  context.mock.timers.enable({ apis: ['setTimeout', 'Date'] })
  const fn = context.mock.fn()
  setTimeout(fn, 1000)

  context.mock.timers.setTime(800)
  // El temporizador no se ejecuta ya que aún no se ha alcanzado la hora
  assert.strictEqual(fn.mock.callCount(), 0)
  assert.strictEqual(Date.now(), 800)

  context.mock.timers.setTime(1200)
  // El temporizador se ejecuta ya que ahora se ha alcanzado la hora
  assert.strictEqual(fn.mock.callCount(), 1)
  assert.strictEqual(Date.now(), 1200)
})

El uso de .runAll() ejecutará todos los temporizadores que están actualmente en la cola. Esto también adelantará la fecha simulada hasta la hora del último temporizador que se ejecutó como si hubiera pasado el tiempo.

js
import assert from 'node:assert'
import { test } from 'node:test'

test('ejecuta temporizadores mientras setTime pasa ticks', context => {
  // Opcionalmente, elija qué simular
  context.mock.timers.enable({ apis: ['setTimeout', 'Date'] })
  const fn = context.mock.fn()
  setTimeout(fn, 1000)
  setTimeout(fn, 2000)
  setTimeout(fn, 3000)

  context.mock.timers.runAll()
  // Todos los temporizadores se ejecutan ya que ahora se ha alcanzado la hora
  assert.strictEqual(fn.mock.callCount(), 3)
  assert.strictEqual(Date.now(), 3000)
})
js
const assert = require('node:assert')
const { test } = require('node:test')

test('ejecuta temporizadores mientras setTime pasa ticks', context => {
  // Opcionalmente, elija qué simular
  context.mock.timers.enable({ apis: ['setTimeout', 'Date'] })
  const fn = context.mock.fn()
  setTimeout(fn, 1000)
  setTimeout(fn, 2000)
  setTimeout(fn, 3000)

  context.mock.timers.runAll()
  // Todos los temporizadores se ejecutan ya que ahora se ha alcanzado la hora
  assert.strictEqual(fn.mock.callCount(), 3)
  assert.strictEqual(Date.now(), 3000)
})

Pruebas de instantáneas

[Estable: 1 - Experimental]

Estable: 1 Estabilidad: 1.0 - Desarrollo temprano

Las pruebas de instantáneas permiten que valores arbitrarios se serialicen en valores de cadena y se comparen con un conjunto de valores buenos conocidos. Los valores buenos conocidos se conocen como instantáneas y se almacenan en un archivo de instantáneas. Los archivos de instantáneas son gestionados por el ejecutor de pruebas, pero están diseñados para ser legibles por humanos para ayudar en la depuración. La mejor práctica es que los archivos de instantáneas se registren en el control de código fuente junto con los archivos de prueba.

Los archivos de instantáneas se generan iniciando Node.js con el indicador de línea de comandos --test-update-snapshots. Se genera un archivo de instantáneas separado para cada archivo de prueba. De forma predeterminada, el archivo de instantáneas tiene el mismo nombre que el archivo de prueba con la extensión de archivo .snapshot. Este comportamiento se puede configurar usando la función snapshot.setResolveSnapshotPath(). Cada aserción de instantánea corresponde a una exportación en el archivo de instantáneas.

A continuación, se muestra un ejemplo de prueba de instantáneas. La primera vez que se ejecuta esta prueba, fallará porque el archivo de instantáneas correspondiente no existe.

js
// test.js
suite('suite de pruebas de instantáneas', () => {
  test('prueba de instantáneas', t => {
    t.assert.snapshot({ value1: 1, value2: 2 })
    t.assert.snapshot(5)
  })
})

Genere el archivo de instantáneas ejecutando el archivo de prueba con --test-update-snapshots. La prueba debería pasar y se creará un archivo llamado test.js.snapshot en el mismo directorio que el archivo de prueba. El contenido del archivo de instantáneas se muestra a continuación. Cada instantánea se identifica con el nombre completo de la prueba y un contador para diferenciar entre las instantáneas de la misma prueba.

js
exports[`suite de pruebas de instantáneas > prueba de instantáneas 1`] = `
{
  "value1": 1,
  "value2": 2
}
`

exports[`suite de pruebas de instantáneas > prueba de instantáneas 2`] = `
5
`

Una vez que se crea el archivo de instantáneas, vuelva a ejecutar las pruebas sin el indicador --test-update-snapshots. Las pruebas deberían pasar ahora.

Reportes de prueba

[Historial]

VersiónCambios
v19.9.0, v18.17.0Los reportes ahora se exponen en node:test/reporters.
v19.6.0, v18.15.0Agregado en: v19.6.0, v18.15.0

El módulo node:test admite pasar flags --test-reporter para que el ejecutor de pruebas utilice un reporte específico.

Se admiten los siguientes reportes integrados:

  • spec El reporte spec muestra los resultados de la prueba en un formato legible por humanos. Este es el reporte predeterminado.
  • tap El reporte tap muestra los resultados de la prueba en el formato TAP.
  • dot El reporte dot muestra los resultados de la prueba en un formato compacto, donde cada prueba exitosa se representa con un ., y cada prueba fallida se representa con una X.
  • junit El reporte junit muestra los resultados de la prueba en un formato XML jUnit
  • lcov El reporte lcov muestra la cobertura de la prueba cuando se utiliza con el flag --experimental-test-coverage.

La salida exacta de estos reportes está sujeta a cambios entre las versiones de Node.js y no se debe confiar en ella de forma programática. Si se requiere acceso programático a la salida del ejecutor de pruebas, utilice los eventos emitidos por el <TestsStream>.

Los reportes están disponibles a través del módulo node:test/reporters:

js
import { tap, spec, dot, junit, lcov } from 'node:test/reporters'
js
const { tap, spec, dot, junit, lcov } = require('node:test/reporters')

Reporteros personalizados

--test-reporter se puede usar para especificar una ruta a un reportero personalizado. Un reportero personalizado es un módulo que exporta un valor aceptado por stream.compose. Los reporteros deben transformar los eventos emitidos por un <TestsStream>

Ejemplo de un reportero personalizado usando <stream.Transform>:

js
import { Transform } from 'node:stream'

const customReporter = new Transform({
  writableObjectMode: true,
  transform(event, encoding, callback) {
    switch (event.type) {
      case 'test:dequeue':
        callback(null, `test ${event.data.name} en cola`)
        break
      case 'test:enqueue':
        callback(null, `test ${event.data.name} encolado`)
        break
      case 'test:watch:drained':
        callback(null, 'cola de vigilancia de prueba vaciada')
        break
      case 'test:start':
        callback(null, `test ${event.data.name} iniciado`)
        break
      case 'test:pass':
        callback(null, `test ${event.data.name} pasó`)
        break
      case 'test:fail':
        callback(null, `test ${event.data.name} falló`)
        break
      case 'test:plan':
        callback(null, 'plan de prueba')
        break
      case 'test:diagnostic':
      case 'test:stderr':
      case 'test:stdout':
        callback(null, event.data.message)
        break
      case 'test:coverage': {
        const { totalLineCount } = event.data.summary.totals
        callback(null, `recuento total de líneas: ${totalLineCount}\n`)
        break
      }
    }
  },
})

export default customReporter
js
const { Transform } = require('node:stream')

const customReporter = new Transform({
  writableObjectMode: true,
  transform(event, encoding, callback) {
    switch (event.type) {
      case 'test:dequeue':
        callback(null, `test ${event.data.name} en cola`)
        break
      case 'test:enqueue':
        callback(null, `test ${event.data.name} encolado`)
        break
      case 'test:watch:drained':
        callback(null, 'cola de vigilancia de prueba vaciada')
        break
      case 'test:start':
        callback(null, `test ${event.data.name} iniciado`)
        break
      case 'test:pass':
        callback(null, `test ${event.data.name} pasó`)
        break
      case 'test:fail':
        callback(null, `test ${event.data.name} falló`)
        break
      case 'test:plan':
        callback(null, 'plan de prueba')
        break
      case 'test:diagnostic':
      case 'test:stderr':
      case 'test:stdout':
        callback(null, event.data.message)
        break
      case 'test:coverage': {
        const { totalLineCount } = event.data.summary.totals
        callback(null, `recuento total de líneas: ${totalLineCount}\n`)
        break
      }
    }
  },
})

module.exports = customReporter

Ejemplo de un reportero personalizado usando una función generadora:

js
export default async function* customReporter(source) {
  for await (const event of source) {
    switch (event.type) {
      case 'test:dequeue':
        yield `test ${event.data.name} en cola\n`
        break
      case 'test:enqueue':
        yield `test ${event.data.name} encolado\n`
        break
      case 'test:watch:drained':
        yield 'cola de vigilancia de prueba vaciada\n'
        break
      case 'test:start':
        yield `test ${event.data.name} iniciado\n`
        break
      case 'test:pass':
        yield `test ${event.data.name} pasó\n`
        break
      case 'test:fail':
        yield `test ${event.data.name} falló\n`
        break
      case 'test:plan':
        yield 'plan de prueba\n'
        break
      case 'test:diagnostic':
      case 'test:stderr':
      case 'test:stdout':
        yield `${event.data.message}\n`
        break
      case 'test:coverage': {
        const { totalLineCount } = event.data.summary.totals
        yield `recuento total de líneas: ${totalLineCount}\n`
        break
      }
    }
  }
}
js
module.exports = async function* customReporter(source) {
  for await (const event of source) {
    switch (event.type) {
      case 'test:dequeue':
        yield `test ${event.data.name} en cola\n`
        break
      case 'test:enqueue':
        yield `test ${event.data.name} encolado\n`
        break
      case 'test:watch:drained':
        yield 'cola de vigilancia de prueba vaciada\n'
        break
      case 'test:start':
        yield `test ${event.data.name} iniciado\n`
        break
      case 'test:pass':
        yield `test ${event.data.name} pasó\n`
        break
      case 'test:fail':
        yield `test ${event.data.name} falló\n`
        break
      case 'test:plan':
        yield 'plan de prueba\n'
        break
      case 'test:diagnostic':
      case 'test:stderr':
      case 'test:stdout':
        yield `${event.data.message}\n`
        break
      case 'test:coverage': {
        const { totalLineCount } = event.data.summary.totals
        yield `recuento total de líneas: ${totalLineCount}\n`
        break
      }
    }
  }
}

El valor proporcionado a --test-reporter debe ser una cadena como la que se usa en un import() en código JavaScript, o un valor proporcionado para --import.

Múltiples reporteros

La bandera --test-reporter se puede especificar varias veces para reportar los resultados de las pruebas en varios formatos. En esta situación, es necesario especificar un destino para cada reportero utilizando --test-reporter-destination. El destino puede ser stdout, stderr o una ruta de archivo. Los reporteros y los destinos se emparejan según el orden en que se especificaron.

En el siguiente ejemplo, el reportero spec se enviará a stdout y el reportero dot se enviará a file.txt:

bash
node --test-reporter=spec --test-reporter=dot --test-reporter-destination=stdout --test-reporter-destination=file.txt

Cuando se especifica un solo reportero, el destino predeterminado será stdout, a menos que se proporcione un destino explícitamente.

run([options])

[Historial]

VersiónCambios
v23.0.0Se agregó la opción cwd.
v23.0.0Se agregaron las opciones de cobertura.
v22.8.0Se agregó la opción isolation.
v22.6.0Se agregó la opción globPatterns.
v22.0.0, v20.14.0Se agregó la opción forceExit.
v20.1.0, v18.17.0Se agregó la opción testNamePatterns.
v18.9.0, v16.19.0Agregado en: v18.9.0, v16.19.0
  • options <Object> Opciones de configuración para ejecutar pruebas. Se admiten las siguientes propiedades:

    • concurrency <number> | <boolean> Si se proporciona un número, se ejecutarán esa cantidad de procesos de prueba en paralelo, donde cada proceso corresponde a un archivo de prueba. Si es true, se ejecutarán os.availableParallelism() - 1 archivos de prueba en paralelo. Si es false, solo se ejecutará un archivo de prueba a la vez. Predeterminado: false.

    • cwd: <string> Especifica el directorio de trabajo actual que utilizará el ejecutor de pruebas. Sirve como ruta base para resolver archivos de acuerdo con el modelo de ejecución del ejecutor de pruebas. Predeterminado: process.cwd().

    • files: <Array> Un array que contiene la lista de archivos para ejecutar. Predeterminado: archivos coincidentes del modelo de ejecución del ejecutor de pruebas.

    • forceExit: <boolean> Configura el ejecutor de pruebas para salir del proceso una vez que todas las pruebas conocidas han terminado de ejecutarse, incluso si el bucle de eventos permanecería activo. Predeterminado: false.

    • globPatterns: <Array> Un array que contiene la lista de patrones glob para que coincidan con los archivos de prueba. Esta opción no se puede usar junto con files. Predeterminado: archivos coincidentes del modelo de ejecución del ejecutor de pruebas.

    • inspectPort <number> | <Function> Establece el puerto del inspector del proceso secundario de prueba. Esto puede ser un número o una función que no toma argumentos y devuelve un número. Si se proporciona un valor nulo, cada proceso obtiene su propio puerto, incrementado desde el process.debugPort del primario. Esta opción se ignora si la opción isolation se establece en 'none' ya que no se generan procesos secundarios. Predeterminado: undefined.

    • isolation <string> Configura el tipo de aislamiento de prueba. Si se establece en 'process', cada archivo de prueba se ejecuta en un proceso secundario separado. Si se establece en 'none', todos los archivos de prueba se ejecutan en el proceso actual. Predeterminado: 'process'.

    • only: <boolean> Si es verdadero, el contexto de prueba solo ejecutará las pruebas que tengan la opción only establecida.

    • setup <Function> Una función que acepta la instancia TestsStream y se puede usar para configurar escuchas antes de que se ejecute cualquier prueba. Predeterminado: undefined.

    • execArgv <Array> Un array de indicadores de CLI para pasar al ejecutable node al generar los subprocesos. Esta opción no tiene efecto cuando isolation es 'none'. Predeterminado: [].

    • argv <Array> Un array de indicadores de CLI para pasar a cada archivo de prueba al generar los subprocesos. Esta opción no tiene efecto cuando isolation es 'none'. Predeterminado: [].

    • signal <AbortSignal> Permite abortar una ejecución de prueba en curso.

    • testNamePatterns <string> | <RegExp> | <Array> Una cadena, RegExp o un array RegExp, que se puede usar para ejecutar solo las pruebas cuyo nombre coincida con el patrón proporcionado. Los patrones de nombres de prueba se interpretan como expresiones regulares de JavaScript. Para cada prueba que se ejecuta, también se ejecutan los enlaces de prueba correspondientes, como beforeEach(). Predeterminado: undefined.

    • testSkipPatterns <string> | <RegExp> | <Array> Una cadena, RegExp o un array RegExp, que se puede usar para excluir la ejecución de pruebas cuyo nombre coincida con el patrón proporcionado. Los patrones de nombres de prueba se interpretan como expresiones regulares de JavaScript. Para cada prueba que se ejecuta, también se ejecutan los enlaces de prueba correspondientes, como beforeEach(). Predeterminado: undefined.

    • timeout <number> Un número de milisegundos después del cual la ejecución de la prueba fallará. Si no se especifica, las subpruebas heredan este valor de su elemento principal. Predeterminado: Infinity.

    • watch <boolean> Si se debe ejecutar o no en modo de observación. Predeterminado: false.

    • shard <Object> Ejecución de pruebas en un fragmento específico. Predeterminado: undefined.

    • index <number> es un entero positivo entre 1 y \<total\> que especifica el índice del fragmento que se va a ejecutar. Esta opción es obligatoria.

    • total <number> es un entero positivo que especifica el número total de fragmentos en los que se dividirán los archivos de prueba. Esta opción es obligatoria.

    • coverage <boolean> habilita la recopilación de cobertura de código. Predeterminado: false.

    • coverageExcludeGlobs <string> | <Array> Excluye archivos específicos de la cobertura de código mediante un patrón glob, que puede coincidir con rutas de archivos absolutas y relativas. Esta propiedad solo se aplica cuando coverage se estableció en true. Si se proporcionan coverageExcludeGlobs y coverageIncludeGlobs, los archivos deben cumplir ambos criterios para incluirse en el informe de cobertura. Predeterminado: undefined.

    • coverageIncludeGlobs <string> | <Array> Incluye archivos específicos en la cobertura de código mediante un patrón glob, que puede coincidir con rutas de archivos absolutas y relativas. Esta propiedad solo se aplica cuando coverage se estableció en true. Si se proporcionan coverageExcludeGlobs y coverageIncludeGlobs, los archivos deben cumplir ambos criterios para incluirse en el informe de cobertura. Predeterminado: undefined.

    • lineCoverage <number> Requiere un porcentaje mínimo de líneas cubiertas. Si la cobertura de código no alcanza el umbral especificado, el proceso saldrá con el código 1. Predeterminado: 0.

    • branchCoverage <number> Requiere un porcentaje mínimo de ramas cubiertas. Si la cobertura de código no alcanza el umbral especificado, el proceso saldrá con el código 1. Predeterminado: 0.

    • functionCoverage <number> Requiere un porcentaje mínimo de funciones cubiertas. Si la cobertura de código no alcanza el umbral especificado, el proceso saldrá con el código 1. Predeterminado: 0.

  • Devuelve: <TestsStream>

Nota: shard se usa para paralelizar horizontalmente la ejecución de pruebas entre máquinas o procesos, ideal para ejecuciones a gran escala en entornos variados. Es incompatible con el modo watch, diseñado para una rápida iteración de código al volver a ejecutar automáticamente las pruebas en los cambios de archivos.

js
import { tap } from 'node:test/reporters'
import { run } from 'node:test'
import process from 'node:process'
import path from 'node:path'

run({ files: [path.resolve('./tests/test.js')] })
  .on('test:fail', () => {
    process.exitCode = 1
  })
  .compose(tap)
  .pipe(process.stdout)
js
const { tap } = require('node:test/reporters')
const { run } = require('node:test')
const path = require('node:path')

run({ files: [path.resolve('./tests/test.js')] })
  .on('test:fail', () => {
    process.exitCode = 1
  })
  .compose(tap)
  .pipe(process.stdout)

suite([name][, options][, fn])

Añadido en: v22.0.0, v20.13.0

  • name <string> El nombre de la suite, que se muestra al informar los resultados de las pruebas. Predeterminado: La propiedad name de fn, o '\<anonymous\>' si fn no tiene nombre.
  • options <Object> Opciones de configuración opcionales para la suite. Esto admite las mismas opciones que test([name][, options][, fn]).
  • fn <Function> | <AsyncFunction> La función de suite que declara pruebas y suites anidadas. El primer argumento de esta función es un objeto SuiteContext. Predeterminado: Una función no-op.
  • Devuelve: <Promise> Cumplida inmediatamente con undefined.

La función suite() se importa del módulo node:test.

suite.skip([name][, options][, fn])

Agregado en: v22.0.0, v20.13.0

Abreviatura para omitir un conjunto de pruebas. Es lo mismo que suite([name], { skip: true }[, fn]).

suite.todo([name][, options][, fn])

Agregado en: v22.0.0, v20.13.0

Abreviatura para marcar un conjunto de pruebas como TODO. Es lo mismo que suite([name], { todo: true }[, fn]).

suite.only([name][, options][, fn])

Agregado en: v22.0.0, v20.13.0

Abreviatura para marcar un conjunto de pruebas como only. Es lo mismo que suite([name], { only: true }[, fn]).

test([name][, options][, fn])

[Historial]

VersiónCambios
v20.2.0, v18.17.0Se agregaron las abreviaturas skip, todo y only.
v18.8.0, v16.18.0Se agregó una opción signal.
v18.7.0, v16.17.0Se agregó una opción timeout.
v18.0.0, v16.17.0Agregado en: v18.0.0, v16.17.0
  • name <string> El nombre de la prueba, que se muestra al informar los resultados de la prueba. Predeterminado: La propiedad name de fn, o '\<anonymous\>' si fn no tiene nombre.

  • options <Objeto> Opciones de configuración para la prueba. Se admiten las siguientes propiedades:

    • concurrency <number> | <boolean> Si se proporciona un número, esa cantidad de pruebas se ejecutarán en paralelo dentro del hilo de la aplicación. Si es true, todas las pruebas asíncronas programadas se ejecutan simultáneamente dentro del hilo. Si es false, solo se ejecuta una prueba a la vez. Si no se especifica, las subpruebas heredan este valor de su padre. Predeterminado: false.
    • only <boolean> Si es verdadero y el contexto de la prueba está configurado para ejecutar pruebas only, entonces se ejecutará esta prueba. De lo contrario, la prueba se omite. Predeterminado: false.
    • signal <AbortSignal> Permite abortar una prueba en curso.
    • skip <boolean> | <string> Si es verdadero, la prueba se omite. Si se proporciona una cadena, esa cadena se muestra en los resultados de la prueba como el motivo para omitir la prueba. Predeterminado: false.
    • todo <boolean> | <string> Si es verdadero, la prueba se marca como TODO. Si se proporciona una cadena, esa cadena se muestra en los resultados de la prueba como la razón por la cual la prueba es TODO. Predeterminado: false.
    • timeout <number> Un número de milisegundos después de los cuales la prueba fallará. Si no se especifica, las subpruebas heredan este valor de su padre. Predeterminado: Infinity.
    • plan <number> El número de afirmaciones y subpruebas que se espera que se ejecuten en la prueba. Si el número de afirmaciones ejecutadas en la prueba no coincide con el número especificado en el plan, la prueba fallará. Predeterminado: undefined.
  • fn <Función> | <FunciónAsíncrona> La función bajo prueba. El primer argumento de esta función es un objeto TestContext. Si la prueba usa devoluciones de llamada, la función de devolución de llamada se pasa como segundo argumento. Predeterminado: Una función no operativa.

  • Devuelve: <Promesa> Se cumple con undefined una vez que se completa la prueba, o inmediatamente si la prueba se ejecuta dentro de un conjunto de pruebas.

La función test() es el valor importado del módulo test. Cada invocación de esta función da como resultado informar la prueba al <TestsStream>.

El objeto TestContext pasado al argumento fn se puede usar para realizar acciones relacionadas con la prueba actual. Los ejemplos incluyen omitir la prueba, agregar información de diagnóstico adicional o crear subpruebas.

test() devuelve una Promesa que se cumple una vez que se completa la prueba. Si se llama a test() dentro de un conjunto de pruebas, se cumple inmediatamente. El valor de retorno generalmente se puede descartar para las pruebas de nivel superior. Sin embargo, el valor de retorno de las subpruebas debe usarse para evitar que la prueba principal termine primero y cancele la subprueba, como se muestra en el siguiente ejemplo.

js
test('prueba de nivel superior', async t => {
  // El setTimeout() en la siguiente subprueba haría que sobreviviera a su
  // prueba principal si se elimina 'await' en la siguiente línea. Una vez que la prueba principal
  // se completa, cancelará cualquier subprueba pendiente.
  await t.test('subprueba de mayor duración', async t => {
    return new Promise((resolve, reject) => {
      setTimeout(resolve, 1000)
    })
  })
})

La opción timeout se puede usar para hacer que la prueba falle si tarda más de timeout milisegundos en completarse. Sin embargo, no es un mecanismo confiable para cancelar pruebas porque una prueba en ejecución podría bloquear el hilo de la aplicación y, por lo tanto, impedir la cancelación programada.

test.skip([name][, options][, fn])

Atajo para omitir una prueba, igual que test([name], { skip: true }[, fn]).

test.todo([name][, options][, fn])

Atajo para marcar una prueba como TODO, igual que test([name], { todo: true }[, fn]).

test.only([name][, options][, fn])

Atajo para marcar una prueba como only, igual que test([name], { only: true }[, fn]).

describe([name][, options][, fn])

Alias de suite().

La función describe() se importa del módulo node:test.

describe.skip([name][, options][, fn])

Atajo para omitir un conjunto de pruebas. Esto es lo mismo que describe([name], { skip: true }[, fn]).

describe.todo([name][, options][, fn])

Atajo para marcar un conjunto de pruebas como TODO. Esto es lo mismo que describe([name], { todo: true }[, fn]).

describe.only([nombre][, opciones][, fn])

Añadido en: v19.8.0, v18.15.0

Abreviatura para marcar un conjunto como only. Esto es lo mismo que describe([nombre], { only: true }[, fn]).

it([nombre][, opciones][, fn])

[Historial]

VersiónCambios
v19.8.0, v18.16.0Llamar a it() ahora es equivalente a llamar a test().
v18.6.0, v16.17.0Añadido en: v18.6.0, v16.17.0

Alias para test().

La función it() se importa desde el módulo node:test.

it.skip([nombre][, opciones][, fn])

Abreviatura para omitir una prueba, lo mismo que it([nombre], { skip: true }[, fn]).

it.todo([nombre][, opciones][, fn])

Abreviatura para marcar una prueba como TODO, lo mismo que it([nombre], { todo: true }[, fn]).

it.only([nombre][, opciones][, fn])

Añadido en: v19.8.0, v18.15.0

Abreviatura para marcar una prueba como only, lo mismo que it([nombre], { only: true }[, fn]).

before([fn][, options])

Añadido en: v18.8.0, v16.18.0

  • fn <Function> | <AsyncFunction> La función de enganche. Si el enganche utiliza devoluciones de llamada, la función de devolución de llamada se pasa como segundo argumento. Predeterminado: Una función no operativa.
  • options <Object> Opciones de configuración para el enganche. Se admiten las siguientes propiedades:
    • signal <AbortSignal> Permite anular un enganche en curso.
    • timeout <number> Número de milisegundos tras los cuales el enganche fallará. Si no se especifica, las subpruebas heredan este valor de su elemento principal. Predeterminado: Infinity.

Esta función crea un enganche que se ejecuta antes de ejecutar un conjunto de pruebas.

js
describe('tests', async () => {
  before(() => console.log('a punto de ejecutar alguna prueba'))
  it('es una subprueba', () => {
    assert.ok('alguna aserción relevante aquí')
  })
})

after([fn][, options])

Añadido en: v18.8.0, v16.18.0

  • fn <Function> | <AsyncFunction> La función de gancho. Si el gancho usa devoluciones de llamada, la función de devolución de llamada se pasa como segundo argumento. Predeterminado: una función sin operación.
  • options <Object> Opciones de configuración para el gancho. Se admiten las siguientes propiedades:
    • signal <AbortSignal> Permite abortar un gancho en curso.
    • timeout <number> Un número de milisegundos después de los cuales el gancho fallará. Si no se especifica, las subpruebas heredan este valor de su elemento principal. Predeterminado: Infinity.

Esta función crea un gancho que se ejecuta después de ejecutar un conjunto de pruebas.

js
describe('tests', async () => {
  after(() => console.log('finalizó la ejecución de pruebas'))
  it('es una subprueba', () => {
    assert.ok('alguna afirmación relevante aquí')
  })
})

Nota: Se garantiza que el gancho after se ejecutará, incluso si las pruebas dentro del conjunto de pruebas fallan.

beforeEach([fn][, options])

Agregado en: v18.8.0, v16.18.0

  • fn <Function> | <AsyncFunction> La función de hook. Si el hook usa callbacks, la función callback se pasa como segundo argumento. Predeterminado: Una función no-op.
  • options <Object> Opciones de configuración para el hook. Se admiten las siguientes propiedades:
    • signal <AbortSignal> Permite abortar un hook en progreso.
    • timeout <number> Un número de milisegundos después de los cuales fallará el hook. Si no se especifica, las subpruebas heredan este valor de su padre. Predeterminado: Infinity.

Esta función crea un hook que se ejecuta antes de cada prueba en la suite actual.

js
describe('tests', async () => {
  beforeEach(() => console.log('a punto de ejecutar una prueba'))
  it('es una subprueba', () => {
    assert.ok('alguna afirmación relevante aquí')
  })
})

afterEach([fn][, options])

Agregado en: v18.8.0, v16.18.0

  • fn <Function> | <AsyncFunction> La función de gancho. Si el gancho usa callbacks, la función de callback se pasa como el segundo argumento. Predeterminado: Una función no-op.
  • options <Object> Opciones de configuración para el gancho. Se admiten las siguientes propiedades:
    • signal <AbortSignal> Permite abortar un gancho en progreso.
    • timeout <number> Un número de milisegundos después de los cuales el gancho fallará. Si no se especifica, las pruebas secundarias heredan este valor de su padre. Predeterminado: Infinity.

Esta función crea un gancho que se ejecuta después de cada prueba en el conjunto actual. El gancho afterEach() se ejecuta incluso si la prueba falla.

js
describe('tests', async () => {
  afterEach(() => console.log('finished running a test'))
  it('is a subtest', () => {
    assert.ok('some relevant assertion here')
  })
})

snapshot

Añadido en: v22.3.0

[Estable: 1 - Experimental]

Estable: 1 Estabilidad: 1.0 - Desarrollo temprano

Un objeto cuyos métodos se utilizan para configurar los ajustes de instantánea predeterminados en el proceso actual. Es posible aplicar la misma configuración a todos los archivos colocando código de configuración común en un módulo precargado con --require o --import.

snapshot.setDefaultSnapshotSerializers(serializers)

Añadido en: v22.3.0

[Estable: 1 - Experimental]

Estable: 1 Estabilidad: 1.0 - Desarrollo temprano

  • serializers <Array> Un array de funciones síncronas utilizadas como serializadores predeterminados para las pruebas de instantáneas.

Esta función se utiliza para personalizar el mecanismo de serialización predeterminado utilizado por el ejecutor de pruebas. De forma predeterminada, el ejecutor de pruebas realiza la serialización llamando a JSON.stringify(value, null, 2) en el valor proporcionado. JSON.stringify() tiene limitaciones con respecto a las estructuras circulares y los tipos de datos admitidos. Si se requiere un mecanismo de serialización más robusto, se debe utilizar esta función.

snapshot.setResolveSnapshotPath(fn)

Agregado en: v22.3.0

[Estable: 1 - Experimental]

Estable: 1 Estabilidad: 1.0 - Desarrollo temprano

  • fn <Función> Una función utilizada para calcular la ubicación del archivo de instantánea. La función recibe la ruta del archivo de prueba como su único argumento. Si la prueba no está asociada a un archivo (por ejemplo, en el REPL), la entrada es indefinida. fn() debe devolver una cadena especificando la ubicación del archivo de instantánea.

Esta función se utiliza para personalizar la ubicación del archivo de instantánea utilizado para las pruebas de instantáneas. De forma predeterminada, el nombre de archivo de instantánea es el mismo que el nombre de archivo del punto de entrada con una extensión de archivo .snapshot.

Clase: MockFunctionContext

Agregado en: v19.1.0, v18.13.0

La clase MockFunctionContext se utiliza para inspeccionar o manipular el comportamiento de las simulaciones creadas a través de las API de MockTracker.

ctx.calls

Agregado en: v19.1.0, v18.13.0

Un getter que devuelve una copia del array interno utilizado para rastrear las llamadas al mock. Cada entrada en el array es un objeto con las siguientes propiedades.

  • arguments <Array> Un array de los argumentos pasados a la función mock.
  • error <any> Si la función mock lanzó un error, esta propiedad contiene el valor lanzado. Predeterminado: undefined.
  • result <any> El valor devuelto por la función mock.
  • stack <Error> Un objeto Error cuyo stack puede ser usado para determinar el sitio de la llamada a la invocación de la función mock.
  • target <Function> | <undefined> Si la función mock es un constructor, este campo contiene la clase que se está construyendo. De lo contrario, será undefined.
  • this <any> El valor this de la función mock.

ctx.callCount()

Agregado en: v19.1.0, v18.13.0

  • Devuelve: <entero> El número de veces que se ha invocado esta simulación.

Esta función devuelve el número de veces que se ha invocado esta simulación. Esta función es más eficiente que verificar ctx.calls.length porque ctx.calls es un getter que crea una copia del array interno de seguimiento de llamadas.

ctx.mockImplementation(implementation)

Agregado en: v19.1.0, v18.13.0

Esta función se utiliza para cambiar el comportamiento de una simulación existente.

El siguiente ejemplo crea una función de simulación utilizando t.mock.fn(), llama a la función de simulación y luego cambia la implementación de la simulación a una función diferente.

js
test('cambia el comportamiento de una simulación', t => {
  let cnt = 0

  function addOne() {
    cnt++
    return cnt
  }

  function addTwo() {
    cnt += 2
    return cnt
  }

  const fn = t.mock.fn(addOne)

  assert.strictEqual(fn(), 1)
  fn.mock.mockImplementation(addTwo)
  assert.strictEqual(fn(), 3)
  assert.strictEqual(fn(), 5)
})

ctx.mockImplementationOnce(implementation[, onCall])

Agregado en: v19.1.0, v18.13.0

  • implementation <Function> | <AsyncFunction> La función que se utilizará como implementación del mock para el número de invocación especificado por onCall.
  • onCall <integer> El número de invocación que usará implementation. Si la invocación especificada ya ha ocurrido, se lanzará una excepción. Predeterminado: El número de la siguiente invocación.

Esta función se utiliza para cambiar el comportamiento de un mock existente para una sola invocación. Una vez que se ha producido la invocación onCall, el mock volverá al comportamiento que habría utilizado si no se hubiera llamado a mockImplementationOnce().

El siguiente ejemplo crea una función mock utilizando t.mock.fn(), llama a la función mock, cambia la implementación del mock a una función diferente para la siguiente invocación y luego reanuda su comportamiento anterior.

js
test('cambia el comportamiento de un mock una vez', t => {
  let cnt = 0

  function addOne() {
    cnt++
    return cnt
  }

  function addTwo() {
    cnt += 2
    return cnt
  }

  const fn = t.mock.fn(addOne)

  assert.strictEqual(fn(), 1)
  fn.mock.mockImplementationOnce(addTwo)
  assert.strictEqual(fn(), 3)
  assert.strictEqual(fn(), 4)
})

ctx.resetCalls()

Agregado en: v19.3.0, v18.13.0

Restablece el historial de llamadas de la función simulada.

ctx.restore()

Agregado en: v19.1.0, v18.13.0

Restablece la implementación de la función simulada a su comportamiento original. El simulacro todavía se puede usar después de llamar a esta función.

Clase: MockModuleContext

Agregado en: v22.3.0, v20.18.0

[Estable: 1 - Experimental]

Estable: 1 Estabilidad: 1.0 - Desarrollo temprano

La clase MockModuleContext se utiliza para manipular el comportamiento de las simulaciones de módulos creadas a través de las API de MockTracker.

ctx.restore()

Agregado en: v22.3.0, v20.18.0

Restablece la implementación del módulo simulado.

Clase: MockTracker

Agregado en: v19.1.0, v18.13.0

La clase MockTracker se utiliza para administrar la funcionalidad de simulación. El módulo de ejecución de pruebas proporciona una exportación de nivel superior mock que es una instancia de MockTracker. Cada prueba también proporciona su propia instancia de MockTracker a través de la propiedad mock del contexto de la prueba.

mock.fn([original[, implementation]][, options])

Agregado en: v19.1.0, v18.13.0

  • original <Function> | <AsyncFunction> Una función opcional para crear un mock. Por defecto: Una función no-op.

  • implementation <Function> | <AsyncFunction> Una función opcional utilizada como implementación de mock para original. Esto es útil para crear mocks que exhiban un comportamiento durante un número específico de llamadas y luego restauren el comportamiento de original. Por defecto: La función especificada por original.

  • options <Object> Opciones de configuración opcionales para la función de mock. Se admiten las siguientes propiedades:

    • times <integer> El número de veces que el mock utilizará el comportamiento de implementation. Una vez que la función de mock ha sido llamada times veces, restaurará automáticamente el comportamiento de original. Este valor debe ser un entero mayor que cero. Por defecto: Infinity.
  • Devuelve: <Proxy> La función mockeada. La función mockeada contiene una propiedad especial mock, que es una instancia de MockFunctionContext, y puede ser utilizada para inspeccionar y cambiar el comportamiento de la función mockeada.

Esta función se utiliza para crear una función de mock.

El siguiente ejemplo crea una función de mock que incrementa un contador en uno en cada invocación. La opción times se utiliza para modificar el comportamiento del mock de modo que las dos primeras invocaciones sumen dos al contador en lugar de uno.

js
test('mockea una función de conteo', t => {
  let cnt = 0

  function addOne() {
    cnt++
    return cnt
  }

  function addTwo() {
    cnt += 2
    return cnt
  }

  const fn = t.mock.fn(addOne, addTwo, { times: 2 })

  assert.strictEqual(fn(), 2)
  assert.strictEqual(fn(), 4)
  assert.strictEqual(fn(), 5)
  assert.strictEqual(fn(), 6)
})

mock.getter(object, methodName[, implementation][, options])

Agregado en: v19.3.0, v18.13.0

Esta función es una sintaxis simplificada para MockTracker.method con options.getter establecido en true.

mock.method(object, methodName[, implementation][, options])

Agregado en: v19.1.0, v18.13.0

  • object <Objeto> El objeto cuyo método se está simulando.

  • methodName <cadena> | <símbolo> El identificador del método en object a simular. Si object[methodName] no es una función, se genera un error.

  • implementation <Función> | <FunciónAsíncrona> Una función opcional utilizada como implementación simulada para object[methodName]. Predeterminado: El método original especificado por object[methodName].

  • options <Objeto> Opciones de configuración opcionales para el método simulado. Se admiten las siguientes propiedades:

    • getter <booleano> Si es true, object[methodName] se trata como un getter. Esta opción no se puede utilizar con la opción setter. Predeterminado: false.
    • setter <booleano> Si es true, object[methodName] se trata como un setter. Esta opción no se puede utilizar con la opción getter. Predeterminado: false.
    • times <entero> La cantidad de veces que la simulación utilizará el comportamiento de implementation. Una vez que se ha llamado al método simulado times veces, restaurará automáticamente el comportamiento original. Este valor debe ser un entero mayor que cero. Predeterminado: Infinity.
  • Devuelve: <Proxy> El método simulado. El método simulado contiene una propiedad especial mock, que es una instancia de MockFunctionContext, y se puede utilizar para inspeccionar y cambiar el comportamiento del método simulado.

Esta función se utiliza para crear una simulación en un método de objeto existente. El siguiente ejemplo demuestra cómo se crea una simulación en un método de objeto existente.

js
test('espía un método de objeto', t => {
  const number = {
    value: 5,
    subtract(a) {
      return this.value - a
    },
  }

  t.mock.method(number, 'subtract')
  assert.strictEqual(number.subtract.mock.callCount(), 0)
  assert.strictEqual(number.subtract(3), 2)
  assert.strictEqual(number.subtract.mock.callCount(), 1)

  const call = number.subtract.mock.calls[0]

  assert.deepStrictEqual(call.arguments, [3])
  assert.strictEqual(call.result, 2)
  assert.strictEqual(call.error, undefined)
  assert.strictEqual(call.target, undefined)
  assert.strictEqual(call.this, number)
})

mock.module(specifier[, options])

Agregado en: v22.3.0, v20.18.0

[Estable: 1 - Experimental]

Estable: 1 Estabilidad: 1 - Desarrollo temprano

  • specifier <string> | <URL> Una cadena que identifica el módulo a simular.

  • options <Object> Opciones de configuración opcionales para el módulo simulado. Se admiten las siguientes propiedades:

    • cache <boolean> Si es false, cada llamada a require() o import() genera un nuevo módulo simulado. Si es true, las llamadas posteriores devolverán el mismo módulo simulado, y el módulo simulado se inserta en la caché de CommonJS. Predeterminado: false.
    • defaultExport <any> Un valor opcional utilizado como la exportación predeterminada del módulo simulado. Si no se proporciona este valor, las simulaciones de ESM no incluyen una exportación predeterminada. Si la simulación es un módulo CommonJS o incorporado, este ajuste se utiliza como el valor de module.exports. Si no se proporciona este valor, las simulaciones de CJS e incorporadas utilizan un objeto vacío como el valor de module.exports.
    • namedExports <Object> Un objeto opcional cuyas claves y valores se utilizan para crear las exportaciones nombradas del módulo simulado. Si la simulación es un módulo CommonJS o incorporado, estos valores se copian en module.exports. Por lo tanto, si una simulación se crea con ambas exportaciones nombradas y una exportación predeterminada no objeto, la simulación lanzará una excepción cuando se utilice como un módulo CJS o incorporado.
  • Devuelve: <MockModuleContext> Un objeto que puede ser utilizado para manipular la simulación.

Esta función se utiliza para simular las exportaciones de módulos ECMAScript, módulos CommonJS y módulos incorporados de Node.js. Cualquier referencia al módulo original antes de la simulación no se ve afectada. Para habilitar la simulación de módulos, Node.js debe iniciarse con el indicador de línea de comandos --experimental-test-module-mocks.

El siguiente ejemplo demuestra cómo se crea una simulación para un módulo.

js
test('simula un módulo integrado en ambos sistemas de módulos', async t => {
  // Crea una simulación de 'node:readline' con una exportación nombrada 'fn', que
  // no existe en el módulo original 'node:readline'.
  const mock = t.mock.module('node:readline', {
    namedExports: {
      fn() {
        return 42
      },
    },
  })

  let esmImpl = await import('node:readline')
  let cjsImpl = require('node:readline')

  // cursorTo() es una exportación del módulo original 'node:readline'.
  assert.strictEqual(esmImpl.cursorTo, undefined)
  assert.strictEqual(cjsImpl.cursorTo, undefined)
  assert.strictEqual(esmImpl.fn(), 42)
  assert.strictEqual(cjsImpl.fn(), 42)

  mock.restore()

  // La simulación se restaura, por lo que se devuelve el módulo incorporado original.
  esmImpl = await import('node:readline')
  cjsImpl = require('node:readline')

  assert.strictEqual(typeof esmImpl.cursorTo, 'function')
  assert.strictEqual(typeof cjsImpl.cursorTo, 'function')
  assert.strictEqual(esmImpl.fn, undefined)
  assert.strictEqual(cjsImpl.fn, undefined)
})

mock.reset()

Agregado en: v19.1.0, v18.13.0

Esta función restaura el comportamiento predeterminado de todas las simulaciones que fueron creadas previamente por este MockTracker y disocia las simulaciones de la instancia MockTracker. Una vez disociadas, las simulaciones aún se pueden usar, pero la instancia MockTracker ya no se puede utilizar para restablecer su comportamiento ni interactuar con ellas de otra manera.

Después de que cada prueba se completa, esta función se llama en el MockTracker del contexto de la prueba. Si el MockTracker global se utiliza de forma extensiva, se recomienda llamar a esta función manualmente.

mock.restoreAll()

Agregado en: v19.1.0, v18.13.0

Esta función restaura el comportamiento predeterminado de todas las simulaciones que fueron creadas previamente por este MockTracker. A diferencia de mock.reset(), mock.restoreAll() no disocia las simulaciones de la instancia MockTracker.

mock.setter(objeto, nombreMétodo[, implementación][, opciones])

Agregado en: v19.3.0, v18.13.0

Esta función es azúcar sintáctico para MockTracker.method con options.setter establecido en true.

Clase: MockTimers

[Historial]

VersiónCambios
v23.1.0Los Mock Timers ahora son estables.
v20.4.0, v18.19.0Añadido en: v20.4.0, v18.19.0

[Estable: 2 - Estable]

Estable: 2 Estabilidad: 2 - Estable

La simulación de temporizadores es una técnica comúnmente utilizada en las pruebas de software para simular y controlar el comportamiento de los temporizadores, como setInterval y setTimeout, sin esperar realmente los intervalos de tiempo especificados.

MockTimers también es capaz de simular el objeto Date.

El MockTracker proporciona una exportación de nivel superior timers que es una instancia de MockTimers.

timers.enable([enableOptions])

[Historial]

VersiónCambios
v21.2.0, v20.11.0Parámetros actualizados para ser un objeto de opciones con las API disponibles y la época inicial predeterminada.
v20.4.0, v18.19.0Añadido en: v20.4.0, v18.19.0

Habilita la simulación de temporizadores para los temporizadores especificados.

  • enableOptions <Object> Opciones de configuración opcionales para habilitar la simulación de temporizadores. Se admiten las siguientes propiedades:
    • apis <Array> Una matriz opcional que contiene los temporizadores a simular. Los valores de temporizador actualmente admitidos son 'setInterval', 'setTimeout', 'setImmediate' y 'Date'. Predeterminado: ['setInterval', 'setTimeout', 'setImmediate', 'Date']. Si no se proporciona ninguna matriz, todas las API relacionadas con el tiempo ('setInterval', 'clearInterval', 'setTimeout', 'clearTimeout', 'setImmediate', 'clearImmediate' y 'Date') se simularán de forma predeterminada.
    • now <number> | <Date> Un número o un objeto Date opcional que representa el tiempo inicial (en milisegundos) para usar como valor para Date.now(). Predeterminado: 0.

Nota: Cuando habilita la simulación para un temporizador específico, su función de limpieza asociada también se simulará implícitamente.

Nota: La simulación de Date afectará el comportamiento de los temporizadores simulados, ya que utilizan el mismo reloj interno.

Ejemplo de uso sin establecer el tiempo inicial:

js
import { mock } from 'node:test'
mock.timers.enable({ apis: ['setInterval'] })
js
const { mock } = require('node:test')
mock.timers.enable({ apis: ['setInterval'] })

El ejemplo anterior habilita la simulación para el temporizador setInterval e implícitamente simula la función clearInterval. Solo se simularán las funciones setInterval y clearInterval de node:timers, node:timers/promises y globalThis.

Ejemplo de uso con el tiempo inicial establecido

js
import { mock } from 'node:test'
mock.timers.enable({ apis: ['Date'], now: 1000 })
js
const { mock } = require('node:test')
mock.timers.enable({ apis: ['Date'], now: 1000 })

Ejemplo de uso con el objeto Date inicial como tiempo establecido

js
import { mock } from 'node:test'
mock.timers.enable({ apis: ['Date'], now: new Date() })
js
const { mock } = require('node:test')
mock.timers.enable({ apis: ['Date'], now: new Date() })

Alternativamente, si llama a mock.timers.enable() sin ningún parámetro:

Se simularán todos los temporizadores ('setInterval', 'clearInterval', 'setTimeout', 'clearTimeout', 'setImmediate' y 'clearImmediate'). Se simularán las funciones setInterval, clearInterval, setTimeout, clearTimeout, setImmediate y clearImmediate de node:timers, node:timers/promises y globalThis. Así como el objeto Date global.

timers.reset()

Añadido en: v20.4.0, v18.19.0

Esta función restaura el comportamiento predeterminado de todas las simulaciones que fueron creadas previamente por esta instancia de MockTimers y desvincula las simulaciones de la instancia de MockTracker.

Nota: Después de que cada prueba se completa, esta función se llama en el MockTracker del contexto de la prueba.

js
import { mock } from 'node:test'
mock.timers.reset()
js
const { mock } = require('node:test')
mock.timers.reset()

timers[Symbol.dispose]()

Llama a timers.reset().

timers.tick([milisegundos])

Añadido en: v20.4.0, v18.19.0

Avanza el tiempo para todos los temporizadores simulados.

  • milisegundos <number> La cantidad de tiempo, en milisegundos, para avanzar los temporizadores. Predeterminado: 1.

Nota: Esto difiere de cómo se comporta setTimeout en Node.js y acepta solo números positivos. En Node.js, setTimeout con números negativos solo se admite por razones de compatibilidad web.

El siguiente ejemplo simula una función setTimeout y al usar .tick avanza en el tiempo, activando todos los temporizadores pendientes.

js
import assert from 'node:assert'
import { test } from 'node:test'

test('simula setTimeout para que se ejecute sincrónicamente sin tener que esperar', context => {
  const fn = context.mock.fn()

  context.mock.timers.enable({ apis: ['setTimeout'] })

  setTimeout(fn, 9999)

  assert.strictEqual(fn.mock.callCount(), 0)

  // Avanzar en el tiempo
  context.mock.timers.tick(9999)

  assert.strictEqual(fn.mock.callCount(), 1)
})
js
const assert = require('node:assert')
const { test } = require('node:test')

test('simula setTimeout para que se ejecute sincrónicamente sin tener que esperar', context => {
  const fn = context.mock.fn()
  context.mock.timers.enable({ apis: ['setTimeout'] })

  setTimeout(fn, 9999)
  assert.strictEqual(fn.mock.callCount(), 0)

  // Avanzar en el tiempo
  context.mock.timers.tick(9999)

  assert.strictEqual(fn.mock.callCount(), 1)
})

Alternativamente, la función .tick se puede llamar muchas veces

js
import assert from 'node:assert'
import { test } from 'node:test'

test('simula setTimeout para que se ejecute sincrónicamente sin tener que esperar', context => {
  const fn = context.mock.fn()
  context.mock.timers.enable({ apis: ['setTimeout'] })
  const nineSecs = 9000
  setTimeout(fn, nineSecs)

  const threeSeconds = 3000
  context.mock.timers.tick(threeSeconds)
  context.mock.timers.tick(threeSeconds)
  context.mock.timers.tick(threeSeconds)

  assert.strictEqual(fn.mock.callCount(), 1)
})
js
const assert = require('node:assert')
const { test } = require('node:test')

test('simula setTimeout para que se ejecute sincrónicamente sin tener que esperar', context => {
  const fn = context.mock.fn()
  context.mock.timers.enable({ apis: ['setTimeout'] })
  const nineSecs = 9000
  setTimeout(fn, nineSecs)

  const threeSeconds = 3000
  context.mock.timers.tick(threeSeconds)
  context.mock.timers.tick(threeSeconds)
  context.mock.timers.tick(threeSeconds)

  assert.strictEqual(fn.mock.callCount(), 1)
})

Avanzar el tiempo usando .tick también avanzará el tiempo para cualquier objeto Date creado después de que se habilitó la simulación (si Date también se configuró para ser simulado).

js
import assert from 'node:assert'
import { test } from 'node:test'

test('simula setTimeout para que se ejecute sincrónicamente sin tener que esperar', context => {
  const fn = context.mock.fn()

  context.mock.timers.enable({ apis: ['setTimeout', 'Date'] })
  setTimeout(fn, 9999)

  assert.strictEqual(fn.mock.callCount(), 0)
  assert.strictEqual(Date.now(), 0)

  // Avanzar en el tiempo
  context.mock.timers.tick(9999)
  assert.strictEqual(fn.mock.callCount(), 1)
  assert.strictEqual(Date.now(), 9999)
})
js
const assert = require('node:assert')
const { test } = require('node:test')

test('simula setTimeout para que se ejecute sincrónicamente sin tener que esperar', context => {
  const fn = context.mock.fn()
  context.mock.timers.enable({ apis: ['setTimeout', 'Date'] })

  setTimeout(fn, 9999)
  assert.strictEqual(fn.mock.callCount(), 0)
  assert.strictEqual(Date.now(), 0)

  // Avanzar en el tiempo
  context.mock.timers.tick(9999)
  assert.strictEqual(fn.mock.callCount(), 1)
  assert.strictEqual(Date.now(), 9999)
})

Usando funciones clear

Como se mencionó, todas las funciones clear de los temporizadores (clearTimeout, clearInterval y clearImmediate) se simulan implícitamente. Echa un vistazo a este ejemplo usando setTimeout:

js
import assert from 'node:assert'
import { test } from 'node:test'

test('simula setTimeout para que se ejecute de forma síncrona sin tener que esperar realmente', context => {
  const fn = context.mock.fn()

  // Opcionalmente, elige qué simular
  context.mock.timers.enable({ apis: ['setTimeout'] })
  const id = setTimeout(fn, 9999)

  // También se simula implícitamente
  clearTimeout(id)
  context.mock.timers.tick(9999)

  // Como ese setTimeout fue borrado, la función simulada nunca será llamada
  assert.strictEqual(fn.mock.callCount(), 0)
})
js
const assert = require('node:assert')
const { test } = require('node:test')

test('simula setTimeout para que se ejecute de forma síncrona sin tener que esperar realmente', context => {
  const fn = context.mock.fn()

  // Opcionalmente, elige qué simular
  context.mock.timers.enable({ apis: ['setTimeout'] })
  const id = setTimeout(fn, 9999)

  // También se simula implícitamente
  clearTimeout(id)
  context.mock.timers.tick(9999)

  // Como ese setTimeout fue borrado, la función simulada nunca será llamada
  assert.strictEqual(fn.mock.callCount(), 0)
})

Trabajando con módulos de temporizadores de Node.js

Una vez que habilitas la simulación de temporizadores, los módulos node:timers, node:timers/promises y los temporizadores del contexto global de Node.js se habilitan:

Nota: La desestructuración de funciones como import { setTimeout } from 'node:timers' actualmente no es compatible con esta API.

js
import assert from 'node:assert'
import { test } from 'node:test'
import nodeTimers from 'node:timers'
import nodeTimersPromises from 'node:timers/promises'

test('simula setTimeout para que se ejecute sincrónicamente sin tener que esperar realmente', async context => {
  const globalTimeoutObjectSpy = context.mock.fn()
  const nodeTimerSpy = context.mock.fn()
  const nodeTimerPromiseSpy = context.mock.fn()

  // Opcionalmente elige qué simular
  context.mock.timers.enable({ apis: ['setTimeout'] })
  setTimeout(globalTimeoutObjectSpy, 9999)
  nodeTimers.setTimeout(nodeTimerSpy, 9999)

  const promesa = nodeTimersPromises.setTimeout(9999).then(nodeTimerPromiseSpy)

  // Avanzar en el tiempo
  context.mock.timers.tick(9999)
  assert.strictEqual(globalTimeoutObjectSpy.mock.callCount(), 1)
  assert.strictEqual(nodeTimerSpy.mock.callCount(), 1)
  await promesa
  assert.strictEqual(nodeTimerPromiseSpy.mock.callCount(), 1)
})
js
const assert = require('node:assert')
const { test } = require('node:test')
const nodeTimers = require('node:timers')
const nodeTimersPromises = require('node:timers/promises')

test('simula setTimeout para que se ejecute sincrónicamente sin tener que esperar realmente', async context => {
  const globalTimeoutObjectSpy = context.mock.fn()
  const nodeTimerSpy = context.mock.fn()
  const nodeTimerPromiseSpy = context.mock.fn()

  // Opcionalmente elige qué simular
  context.mock.timers.enable({ apis: ['setTimeout'] })
  setTimeout(globalTimeoutObjectSpy, 9999)
  nodeTimers.setTimeout(nodeTimerSpy, 9999)

  const promesa = nodeTimersPromises.setTimeout(9999).then(nodeTimerPromiseSpy)

  // Avanzar en el tiempo
  context.mock.timers.tick(9999)
  assert.strictEqual(globalTimeoutObjectSpy.mock.callCount(), 1)
  assert.strictEqual(nodeTimerSpy.mock.callCount(), 1)
  await promesa
  assert.strictEqual(nodeTimerPromiseSpy.mock.callCount(), 1)
})

En Node.js, setInterval de node:timers/promises es un AsyncGenerator y también es compatible con esta API:

js
import assert from 'node:assert'
import { test } from 'node:test'
import nodeTimersPromises from 'node:timers/promises'
test('debería avanzar cinco veces probando un caso de uso real', async context => {
  context.mock.timers.enable({ apis: ['setInterval'] })

  const expectedIterations = 3
  const interval = 1000
  const startedAt = Date.now()
  async function run() {
    const times = []
    for await (const time of nodeTimersPromises.setInterval(interval, startedAt)) {
      times.push(time)
      if (times.length === expectedIterations) break
    }
    return times
  }

  const r = run()
  context.mock.timers.tick(interval)
  context.mock.timers.tick(interval)
  context.mock.timers.tick(interval)

  const timeResults = await r
  assert.strictEqual(timeResults.length, expectedIterations)
  for (let it = 1; it < expectedIterations; it++) {
    assert.strictEqual(timeResults[it - 1], startedAt + interval * it)
  }
})
js
const assert = require('node:assert')
const { test } = require('node:test')
const nodeTimersPromises = require('node:timers/promises')
test('debería avanzar cinco veces probando un caso de uso real', async context => {
  context.mock.timers.enable({ apis: ['setInterval'] })

  const expectedIterations = 3
  const interval = 1000
  const startedAt = Date.now()
  async function run() {
    const times = []
    for await (const time of nodeTimersPromises.setInterval(interval, startedAt)) {
      times.push(time)
      if (times.length === expectedIterations) break
    }
    return times
  }

  const r = run()
  context.mock.timers.tick(interval)
  context.mock.timers.tick(interval)
  context.mock.timers.tick(interval)

  const timeResults = await r
  assert.strictEqual(timeResults.length, expectedIterations)
  for (let it = 1; it < expectedIterations; it++) {
    assert.strictEqual(timeResults[it - 1], startedAt + interval * it)
  }
})

timers.runAll()

Agregado en: v20.4.0, v18.19.0

Activa inmediatamente todos los temporizadores simulados pendientes. Si el objeto Date también está simulado, también avanzará el objeto Date hasta el tiempo del temporizador más lejano.

El ejemplo siguiente activa todos los temporizadores pendientes de inmediato, lo que hace que se ejecuten sin demora alguna.

js
import assert from 'node:assert'
import { test } from 'node:test'

test('runAll functions following the given order', context => {
  context.mock.timers.enable({ apis: ['setTimeout', 'Date'] })
  const results = []
  setTimeout(() => results.push(1), 9999)

  // Observe que si ambos temporizadores tienen el mismo tiempo de espera,
  // se garantiza el orden de ejecución
  setTimeout(() => results.push(3), 8888)
  setTimeout(() => results.push(2), 8888)

  assert.deepStrictEqual(results, [])

  context.mock.timers.runAll()
  assert.deepStrictEqual(results, [3, 2, 1])
  // El objeto Date también se avanza al tiempo del temporizador más lejano
  assert.strictEqual(Date.now(), 9999)
})
js
const assert = require('node:assert')
const { test } = require('node:test')

test('runAll functions following the given order', context => {
  context.mock.timers.enable({ apis: ['setTimeout', 'Date'] })
  const results = []
  setTimeout(() => results.push(1), 9999)

  // Observe que si ambos temporizadores tienen el mismo tiempo de espera,
  // se garantiza el orden de ejecución
  setTimeout(() => results.push(3), 8888)
  setTimeout(() => results.push(2), 8888)

  assert.deepStrictEqual(results, [])

  context.mock.timers.runAll()
  assert.deepStrictEqual(results, [3, 2, 1])
  // El objeto Date también se avanza al tiempo del temporizador más lejano
  assert.strictEqual(Date.now(), 9999)
})

Nota: La función runAll() está diseñada específicamente para activar temporizadores en el contexto de la simulación de temporizadores. No tiene ningún efecto sobre los relojes del sistema en tiempo real ni sobre los temporizadores reales fuera del entorno de simulación.

timers.setTime(milliseconds)

Agregado en: v21.2.0, v20.11.0

Establece la marca de tiempo Unix actual que se utilizará como referencia para cualquier objeto Date simulado.

js
import assert from 'node:assert'
import { test } from 'node:test'

test('ejecutar todas las funciones siguiendo el orden dado', context => {
  const now = Date.now()
  const setTime = 1000
  // Date.now no está simulado
  assert.deepStrictEqual(Date.now(), now)

  context.mock.timers.enable({ apis: ['Date'] })
  context.mock.timers.setTime(setTime)
  // Date.now ahora es 1000
  assert.strictEqual(Date.now(), setTime)
})
js
const assert = require('node:assert')
const { test } = require('node:test')

test('setTime reemplaza la hora actual', context => {
  const now = Date.now()
  const setTime = 1000
  // Date.now no está simulado
  assert.deepStrictEqual(Date.now(), now)

  context.mock.timers.enable({ apis: ['Date'] })
  context.mock.timers.setTime(setTime)
  // Date.now ahora es 1000
  assert.strictEqual(Date.now(), setTime)
})

Fechas y Temporizadores trabajando juntos

Los objetos de fechas y temporizadores son dependientes entre sí. Si utilizas setTime() para pasar la hora actual al objeto Date simulado, los temporizadores establecidos con setTimeout y setInterval no se verán afectados.

Sin embargo, el método tick avanzará el objeto Date simulado.

js
import assert from 'node:assert'
import { test } from 'node:test'

test('ejecutar todas las funciones siguiendo el orden dado', context => {
  context.mock.timers.enable({ apis: ['setTimeout', 'Date'] })
  const results = []
  setTimeout(() => results.push(1), 9999)

  assert.deepStrictEqual(results, [])
  context.mock.timers.setTime(12000)
  assert.deepStrictEqual(results, [])
  // La fecha avanza pero los temporizadores no hacen tick
  assert.strictEqual(Date.now(), 12000)
})
js
const assert = require('node:assert')
const { test } = require('node:test')

test('ejecutar todas las funciones siguiendo el orden dado', context => {
  context.mock.timers.enable({ apis: ['setTimeout', 'Date'] })
  const results = []
  setTimeout(() => results.push(1), 9999)

  assert.deepStrictEqual(results, [])
  context.mock.timers.setTime(12000)
  assert.deepStrictEqual(results, [])
  // La fecha avanza pero los temporizadores no hacen tick
  assert.strictEqual(Date.now(), 12000)
})

Clase: TestsStream

[Historial]

VersiónCambios
v20.0.0, v19.9.0, v18.17.0Se agregó el tipo a los eventos test:pass y test:fail para cuando la prueba es un conjunto.
v18.9.0, v16.19.0Agregado en: v18.9.0, v16.19.0

Una llamada exitosa al método run() devolverá un nuevo objeto <TestsStream>, transmitiendo una serie de eventos que representan la ejecución de las pruebas. TestsStream emitirá eventos, en el orden de la definición de las pruebas.

Algunos de los eventos se emiten garantizadamente en el mismo orden en que se definen las pruebas, mientras que otros se emiten en el orden en que se ejecutan las pruebas.

Evento: 'test:coverage'

  • data <Objeto>

    • summary <Objeto> Un objeto que contiene el informe de cobertura.

    • files <Array> Un array de informes de cobertura para archivos individuales. Cada informe es un objeto con el siguiente esquema:

    • path <string> La ruta absoluta del archivo.

    • totalLineCount <number> El número total de líneas.

    • totalBranchCount <number> El número total de ramas.

    • totalFunctionCount <number> El número total de funciones.

    • coveredLineCount <number> El número de líneas cubiertas.

    • coveredBranchCount <number> El número de ramas cubiertas.

    • coveredFunctionCount <number> El número de funciones cubiertas.

    • coveredLinePercent <number> El porcentaje de líneas cubiertas.

    • coveredBranchPercent <number> El porcentaje de ramas cubiertas.

    • coveredFunctionPercent <number> El porcentaje de funciones cubiertas.

    • functions <Array> Un array de funciones que representan la cobertura de funciones.

    • name <string> El nombre de la función.

    • line <number> El número de línea donde se define la función.

    • count <number> El número de veces que se llamó a la función.

    • branches <Array> Un array de ramas que representan la cobertura de ramas.

    • line <number> El número de línea donde se define la rama.

    • count <number> El número de veces que se tomó la rama.

    • lines <Array> Un array de líneas que representan los números de línea y el número de veces que se cubrieron.

    • line <number> El número de línea.

    • count <number> El número de veces que se cubrió la línea.

    • thresholds <Objeto> Un objeto que indica si se alcanza o no la cobertura para cada tipo de cobertura.

    • function <number> El umbral de cobertura de la función.

    • branch <number> El umbral de cobertura de la rama.

    • line <number> El umbral de cobertura de la línea.

    • totals <Objeto> Un objeto que contiene un resumen de la cobertura de todos los archivos.

    • totalLineCount <number> El número total de líneas.

    • totalBranchCount <number> El número total de ramas.

    • totalFunctionCount <number> El número total de funciones.

    • coveredLineCount <number> El número de líneas cubiertas.

    • coveredBranchCount <number> El número de ramas cubiertas.

    • coveredFunctionCount <number> El número de funciones cubiertas.

    • coveredLinePercent <number> El porcentaje de líneas cubiertas.

    • coveredBranchPercent <number> El porcentaje de ramas cubiertas.

    • coveredFunctionPercent <number> El porcentaje de funciones cubiertas.

    • workingDirectory <string> El directorio de trabajo cuando comenzó la cobertura de código. Esto es útil para mostrar nombres de ruta relativos en caso de que las pruebas hayan cambiado el directorio de trabajo del proceso de Node.js.

    • nesting <number> El nivel de anidamiento de la prueba.

Emitido cuando la cobertura de código está habilitada y todas las pruebas se han completado.

Evento: 'test:complete'

Se emite cuando una prueba completa su ejecución. Este evento no se emite en el mismo orden en que se definen las pruebas. Los eventos ordenados de declaración correspondientes son 'test:pass' y 'test:fail'.

Evento: 'test:dequeue'

Emitido cuando una prueba se retira de la cola, justo antes de que se ejecute. No se garantiza que este evento se emita en el mismo orden en que se definen las pruebas. El evento de orden de declaración correspondiente es 'test:start'.

Evento: 'test:diagnostic'

  • data <Objeto>
    • column <número> | <undefined> El número de columna donde se define la prueba, o undefined si la prueba se ejecutó a través del REPL.
    • file <string> | <undefined> La ruta del archivo de prueba, undefined si la prueba se ejecutó a través del REPL.
    • line <número> | <undefined> El número de línea donde se define la prueba, o undefined si la prueba se ejecutó a través del REPL.
    • message <string> El mensaje de diagnóstico.
    • nesting <número> El nivel de anidamiento de la prueba.

Emitido cuando se llama a context.diagnostic. Se garantiza que este evento se emitirá en el mismo orden en que se definen las pruebas.

Evento: 'test:enqueue'

  • data <Object>
    • column <number> | <undefined> El número de columna donde se define la prueba, o undefined si la prueba se ejecutó a través del REPL.
    • file <string> | <undefined> La ruta del archivo de prueba, undefined si la prueba se ejecutó a través del REPL.
    • line <number> | <undefined> El número de línea donde se define la prueba, o undefined si la prueba se ejecutó a través del REPL.
    • name <string> El nombre de la prueba.
    • nesting <number> El nivel de anidamiento de la prueba.

Se emite cuando una prueba se pone en cola para su ejecución.

Evento: 'test:fail'

Se emite cuando falla una prueba. Se garantiza que este evento se emitirá en el mismo orden en que se definen las pruebas. El evento de ejecución correspondiente es 'test:complete'.

Evento: 'test:pass'

Se emite cuando una prueba pasa. Se garantiza que este evento se emite en el mismo orden en que se definen las pruebas. El evento de orden de ejecución correspondiente es 'test:complete'.

Evento: 'test:plan'

  • data <Object>
    • column <number> | <undefined> El número de columna donde se define la prueba, o undefined si la prueba se ejecutó a través del REPL.
    • file <string> | <undefined> La ruta del archivo de prueba, undefined si la prueba se ejecutó a través del REPL.
    • line <number> | <undefined> El número de línea donde se define la prueba, o undefined si la prueba se ejecutó a través del REPL.
    • nesting <number> El nivel de anidamiento de la prueba.
    • count <number> El número de subpruebas que se han ejecutado.

Emitido cuando todas las subpruebas se han completado para una prueba dada. Se garantiza que este evento se emite en el mismo orden en que se definen las pruebas.

Evento: 'test:start'

  • data <Objeto>
    • column <número> | <undefined> El número de columna donde se define la prueba, o undefined si la prueba se ejecutó a través del REPL.
    • file <string> | <undefined> La ruta del archivo de prueba, undefined si la prueba se ejecutó a través del REPL.
    • line <número> | <undefined> El número de línea donde se define la prueba, o undefined si la prueba se ejecutó a través del REPL.
    • name <string> El nombre de la prueba.
    • nesting <número> El nivel de anidamiento de la prueba.

Emitido cuando una prueba comienza a informar su propio estado y el de sus subpruebas. Se garantiza que este evento se emitirá en el mismo orden en que se definen las pruebas. El evento de orden de ejecución correspondiente es 'test:dequeue'.

Evento: 'test:stderr'

Emitido cuando una prueba en ejecución escribe en stderr. Este evento solo se emite si se pasa el indicador --test. No se garantiza que este evento se emita en el mismo orden en que se definen las pruebas.

Evento: 'test:stdout'

Emitido cuando una prueba en ejecución escribe en stdout. Este evento solo se emite si se pasa el indicador --test. No se garantiza que este evento se emita en el mismo orden en que se definen las pruebas.

Evento: 'test:summary'

  • data <Objeto>

    • counts <Objeto> Un objeto que contiene los recuentos de varios resultados de pruebas.

    • cancelled <número> El número total de pruebas canceladas.

    • failed <número> El número total de pruebas fallidas.

    • passed <número> El número total de pruebas aprobadas.

    • skipped <número> El número total de pruebas omitidas.

    • suites <número> El número total de suites ejecutadas.

    • tests <número> El número total de pruebas ejecutadas, excluyendo las suites.

    • todo <número> El número total de pruebas TODO.

    • topLevel <número> El número total de pruebas y suites de nivel superior.

    • duration_ms <número> La duración de la ejecución de la prueba en milisegundos.

    • file <cadena> | <indefinido> La ruta del archivo de prueba que generó el resumen. Si el resumen corresponde a varios archivos, este valor es undefined.

    • success <booleano> Indica si la ejecución de la prueba se considera exitosa o no. Si se produce alguna condición de error, como una prueba fallida o un umbral de cobertura incumplido, este valor se establecerá en false.

Se emite cuando finaliza una ejecución de prueba. Este evento contiene métricas relacionadas con la ejecución de la prueba completada y es útil para determinar si una ejecución de prueba pasó o falló. Si se utiliza el aislamiento de prueba a nivel de proceso, se genera un evento 'test:summary' para cada archivo de prueba, además de un resumen acumulativo final.

Evento: 'test:watch:drained'

Se emite cuando no hay más pruebas en cola para su ejecución en modo de vigilancia.

Clase: TestContext

[Historial]

VersiónCambios
v20.1.0, v18.17.0Se añadió la función before a TestContext.
v18.0.0, v16.17.0Añadido en: v18.0.0, v16.17.0

Se pasa una instancia de TestContext a cada función de prueba para interactuar con el ejecutor de pruebas. Sin embargo, el constructor TestContext no se expone como parte de la API.

context.before([fn][, options])

Añadido en: v20.1.0, v18.17.0

  • fn <Function> | <AsyncFunction> La función de hook. El primer argumento de esta función es un objeto TestContext. Si el hook usa callbacks, la función de callback se pasa como segundo argumento. Predeterminado: una función no-op.
  • options <Object> Opciones de configuración para el hook. Se admiten las siguientes propiedades:
    • signal <AbortSignal> Permite abortar un hook en curso.
    • timeout <number> Un número de milisegundos después del cual fallará el hook. Si no se especifica, las subpruebas heredan este valor de su padre. Predeterminado: Infinity.

Esta función se utiliza para crear un hook que se ejecuta antes de la subprueba de la prueba actual.

context.beforeEach([fn][, options])

Añadido en: v18.8.0, v16.18.0

  • fn <Function> | <AsyncFunction> La función de hook. El primer argumento de esta función es un objeto TestContext. Si el hook usa callbacks, la función de callback se pasa como segundo argumento. Predeterminado: Una función no-op.
  • options <Object> Opciones de configuración para el hook. Se admiten las siguientes propiedades:
    • signal <AbortSignal> Permite abortar un hook en curso.
    • timeout <number> Un número de milisegundos después de los cuales el hook fallará. Si no se especifica, las pruebas secundarias heredan este valor de su padre. Predeterminado: Infinity.

Esta función se utiliza para crear un hook que se ejecuta antes de cada subprueba de la prueba actual.

js
test('prueba de nivel superior', async t => {
  t.beforeEach(t => t.diagnostic(`a punto de ejecutar ${t.name}`))
  await t.test('Esta es una subprueba', t => {
    assert.ok('alguna aserción relevante aquí')
  })
})

context.after([fn][, options])

Añadido en: v19.3.0, v18.13.0

  • fn <Function> | <AsyncFunction> La función de enganche. El primer argumento de esta función es un objeto TestContext. Si el enganche usa devoluciones de llamada, la función de devolución de llamada se pasa como segundo argumento. Predeterminado: Una función que no realiza ninguna operación.
  • options <Object> Opciones de configuración para el enganche. Se admiten las siguientes propiedades:
    • signal <AbortSignal> Permite abortar un enganche en curso.
    • timeout <number> Un número de milisegundos después del cual el enganche fallará. Si no se especifica, las subpruebas heredan este valor de su padre. Predeterminado: Infinity.

Esta función se utiliza para crear un enganche que se ejecuta después de que finaliza la prueba actual.

js
test('prueba de nivel superior', async t => {
  t.after(t => t.diagnostic(`terminó de ejecutar ${t.name}`))
  assert.ok('alguna aserción relevante aquí')
})

context.afterEach([fn][, options])

Añadido en: v18.8.0, v16.18.0

  • fn <Function> | <AsyncFunction> La función de hook. El primer argumento de esta función es un objeto TestContext. Si el hook usa callbacks, la función de callback se pasa como segundo argumento. Predeterminado: una función no-op.
  • options <Object> Opciones de configuración para el hook. Se admiten las siguientes propiedades:
    • signal <AbortSignal> Permite abortar un hook en curso.
    • timeout <number> Un número de milisegundos después de los cuales el hook fallará. Si no se especifica, los subtests heredan este valor de su padre. Predeterminado: Infinity.

Esta función se usa para crear un hook que se ejecuta después de cada subtest del test actual.

js
test('test de nivel superior', async t => {
  t.afterEach(t => t.diagnostic(`terminó de ejecutarse ${t.name}`))
  await t.test('Este es un subtest', t => {
    assert.ok('alguna afirmación relevante aquí')
  })
})

context.assert

Agregado en: v22.2.0, v20.15.0

Un objeto que contiene métodos de aserción vinculados al context. Las funciones de nivel superior del módulo node:assert se exponen aquí con el propósito de crear planes de prueba.

js
test('prueba', t => {
  t.plan(1)
  t.assert.strictEqual(true, true)
})

context.assert.snapshot(value[, options])

Agregado en: v22.3.0

[Estable: 1 - Experimental]

Estable: 1 Estabilidad: 1.0 - Desarrollo temprano

  • value <any> Un valor para serializar a una cadena. Si Node.js se inició con la bandera --test-update-snapshots, el valor serializado se escribe en el archivo de instantáneas. De lo contrario, el valor serializado se compara con el valor correspondiente en el archivo de instantáneas existente.
  • options <Object> Opciones de configuración opcionales. Se admiten las siguientes propiedades:
    • serializers <Array> Un arreglo de funciones síncronas utilizadas para serializar value en una cadena. value se pasa como el único argumento a la primera función serializadora. El valor de retorno de cada serializador se pasa como entrada al siguiente serializador. Una vez que se han ejecutado todos los serializadores, el valor resultante se convierte en una cadena. Predeterminado: Si no se proporcionan serializadores, se utilizan los serializadores predeterminados del ejecutor de pruebas.

Esta función implementa aserciones para pruebas de instantáneas.

js
test('prueba de instantánea con serialización predeterminada', t => {
  t.assert.snapshot({ value1: 1, value2: 2 })
})

test('prueba de instantánea con serialización personalizada', t => {
  t.assert.snapshot(
    { value3: 3, value4: 4 },
    {
      serializers: [value => JSON.stringify(value)],
    }
  )
})

context.diagnostic(message)

Añadido en: v18.0.0, v16.17.0

  • message <string> Mensaje que se va a informar.

Esta función se utiliza para escribir diagnósticos en la salida. Cualquier información de diagnóstico se incluye al final de los resultados de la prueba. Esta función no devuelve un valor.

js
test('prueba de nivel superior', t => {
  t.diagnostic('Un mensaje de diagnóstico')
})

context.filePath

Añadido en: v22.6.0, v20.16.0

La ruta absoluta del archivo de prueba que creó la prueba actual. Si un archivo de prueba importa módulos adicionales que generan pruebas, las pruebas importadas devolverán la ruta del archivo de prueba raíz.

context.fullName

Añadido en: v22.3.0

El nombre de la prueba y cada uno de sus antecesores, separados por \>.

context.name

Añadido en: v18.8.0, v16.18.0

El nombre de la prueba.

context.plan(count)

[Historial]

VersiónCambios
v23.4.0Esta función ya no es experimental.
v22.2.0, v20.15.0Añadido en: v22.2.0, v20.15.0
  • count <number> El número de aserciones y subpruebas que se espera que se ejecuten.

Esta función se utiliza para establecer el número de aserciones y subpruebas que se espera que se ejecuten dentro de la prueba. Si el número de aserciones y subpruebas que se ejecutan no coincide con el recuento esperado, la prueba fallará.

js
test('prueba de nivel superior', t => {
  t.plan(2)
  t.assert.ok('alguna aserción relevante aquí')
  t.test('subprueba', () => {})
})

Cuando se trabaja con código asíncrono, la función plan se puede utilizar para garantizar que se ejecute el número correcto de aserciones:

js
test('planificación con streams', (t, done) => {
  function* generate() {
    yield 'a'
    yield 'b'
    yield 'c'
  }
  const expected = ['a', 'b', 'c']
  t.plan(expected.length)
  const stream = Readable.from(generate())
  stream.on('data', chunk => {
    t.assert.strictEqual(chunk, expected.shift())
  })

  stream.on('end', () => {
    done()
  })
})

context.runOnly(shouldRunOnlyTests)

Agregado en: v18.0.0, v16.17.0

  • shouldRunOnlyTests <boolean> Indica si se deben ejecutar o no solo las pruebas con la opción only establecida.

Si shouldRunOnlyTests es verdadero, el contexto de prueba solo ejecutará las pruebas que tengan la opción only establecida. De lo contrario, se ejecutarán todas las pruebas. Si Node.js no se inició con la opción de línea de comandos --test-only, esta función no tiene efecto.

js
test('prueba de nivel superior', t => {
  // El contexto de prueba se puede configurar para ejecutar subpruebas con la opción 'only'.
  t.runOnly(true)
  return Promise.all([t.test('esta subprueba ahora se omite'), t.test('esta subprueba se ejecuta', { only: true })])
})

context.signal

Agregado en: v18.7.0, v16.17.0

Se puede utilizar para abortar subtareas de prueba cuando la prueba ha sido abortada.

js
test('prueba de nivel superior', async t => {
  await fetch('some/uri', { signal: t.signal })
})

context.skip([mensaje])

Agregado en: v18.0.0, v16.17.0

  • mensaje <string> Mensaje de omisión opcional.

Esta función hace que la salida de la prueba indique que la prueba se ha omitido. Si se proporciona mensaje, se incluye en la salida. La llamada a skip() no termina la ejecución de la función de prueba. Esta función no devuelve ningún valor.

js
test('prueba de nivel superior', t => {
  // Asegúrate de regresar aquí también si la prueba contiene lógica adicional.
  t.skip('esto se omite')
})

context.todo([mensaje])

Agregado en: v18.0.0, v16.17.0

Esta función agrega una directiva TODO a la salida de la prueba. Si se proporciona mensaje, se incluye en la salida. La llamada a todo() no termina la ejecución de la función de prueba. Esta función no devuelve ningún valor.

js
test('prueba de nivel superior', t => {
  // Esta prueba está marcada como `TODO`
  t.todo('esto es un todo')
})

context.test([name][, options][, fn])

[Historial]

VersiónCambios
v18.8.0, v16.18.0Se agrega una opción signal.
v18.7.0, v16.17.0Se agrega una opción timeout.
v18.0.0, v16.17.0Agregado en: v18.0.0, v16.17.0
  • name <string> El nombre de la subprueba, que se muestra al informar los resultados de la prueba. Predeterminado: La propiedad name de fn, o '\<anonymous\>' si fn no tiene nombre.

  • options <Object> Opciones de configuración para la subprueba. Se admiten las siguientes propiedades:

    • concurrency <number> | <boolean> | <null> Si se proporciona un número, esa cantidad de pruebas se ejecutaría en paralelo dentro del hilo de la aplicación. Si es true, ejecutaría todas las subpruebas en paralelo. Si es false, solo ejecutaría una prueba a la vez. Si no se especifica, las subpruebas heredan este valor de su padre. Predeterminado: null.
    • only <boolean> Si es verdadero, y el contexto de la prueba está configurado para ejecutar pruebas only, entonces esta prueba se ejecutará. De lo contrario, la prueba se omite. Predeterminado: false.
    • signal <AbortSignal> Permite abortar una prueba en curso.
    • skip <boolean> | <string> Si es verdadero, la prueba se omite. Si se proporciona una cadena, esa cadena se muestra en los resultados de la prueba como el motivo para omitir la prueba. Predeterminado: false.
    • todo <boolean> | <string> Si es verdadero, la prueba se marca como TODO. Si se proporciona una cadena, esa cadena se muestra en los resultados de la prueba como la razón por la cual la prueba es TODO. Predeterminado: false.
    • timeout <number> Una cantidad de milisegundos después de los cuales la prueba fallará. Si no se especifica, las subpruebas heredan este valor de su padre. Predeterminado: Infinity.
    • plan <number> El número de aserciones y subpruebas que se espera ejecutar en la prueba. Si el número de aserciones ejecutadas en la prueba no coincide con el número especificado en el plan, la prueba fallará. Predeterminado: undefined.
  • fn <Function> | <AsyncFunction> La función bajo prueba. El primer argumento de esta función es un objeto TestContext. Si la prueba usa devoluciones de llamada, la función de devolución de llamada se pasa como el segundo argumento. Predeterminado: Una función no operativa.

  • Devuelve: <Promise> Cumplida con undefined una vez que se completa la prueba.

Esta función se usa para crear subpruebas bajo la prueba actual. Esta función se comporta de la misma manera que la función test() de nivel superior.

js
test('prueba de nivel superior', async t => {
  await t.test('Esta es una subprueba', { only: false, skip: false, concurrency: 1, todo: false, plan: 1 }, t => {
    t.assert.ok('alguna aserción relevante aquí')
  })
})

Clase: SuiteContext

Añadido en: v18.7.0, v16.17.0

Se pasa una instancia de SuiteContext a cada función de suite para interactuar con el ejecutor de pruebas. Sin embargo, el constructor de SuiteContext no se expone como parte de la API.

context.filePath

Añadido en: v22.6.0

La ruta absoluta del archivo de prueba que creó la suite actual. Si un archivo de prueba importa módulos adicionales que generan suites, las suites importadas devolverán la ruta del archivo de prueba raíz.

context.name

Añadido en: v18.8.0, v16.18.0

El nombre de la suite.

context.signal

Añadido en: v18.7.0, v16.17.0

Se puede utilizar para abortar subtareas de prueba cuando la prueba ha sido abortada.