Skip to content

Exécuteur de tests

[Historique]

VersionChangements
v20.0.0L'exécuteur de tests est désormais stable.
v18.0.0, v16.17.0Ajouté dans : v18.0.0, v16.17.0

[Stable : 2 - Stable]

Stable : 2 Stabilité : 2 - Stable

Code source : lib/test.js

Le module node:test facilite la création de tests JavaScript. Pour y accéder :

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

Ce module n'est disponible que sous le schéma node:.

Les tests créés via le module test consistent en une fonction unique qui est traitée de l'une des trois manières suivantes :

L'exemple suivant illustre la manière dont les tests sont écrits à l'aide du module test.

js
test('test synchrone réussi', t => {
  // Ce test réussit car il ne lève pas d'exception.
  assert.strictEqual(1, 1)
})

test('test synchrone échoué', t => {
  // Ce test échoue car il lève une exception.
  assert.strictEqual(1, 2)
})

test('test asynchrone réussi', async t => {
  // Ce test réussit car la Promesse retournée par la fonction async
  // est résolue et non rejetée.
  assert.strictEqual(1, 1)
})

test('test asynchrone échoué', async t => {
  // Ce test échoue car la Promesse retournée par la fonction async
  // est rejetée.
  assert.strictEqual(1, 2)
})

test('test échoué utilisant des Promesses', t => {
  // Les Promesses peuvent aussi être utilisées directement.
  return new Promise((resolve, reject) => {
    setImmediate(() => {
      reject(new Error('cela fera échouer le test'))
    })
  })
})

test('test réussi avec rappel', (t, done) => {
  // done() est la fonction de rappel. Lorsque setImmediate() s'exécute, il appelle
  // done() sans arguments.
  setImmediate(done)
})

test('test échoué avec rappel', (t, done) => {
  // Lorsque setImmediate() s'exécute, done() est appelé avec un objet Error et
  // le test échoue.
  setImmediate(() => {
    done(new Error('échec du rappel'))
  })
})

Si des tests échouent, le code de sortie du processus est défini sur 1.

Sous-tests

La méthode test() du contexte de test permet de créer des sous-tests. Elle vous permet de structurer vos tests de manière hiérarchique, où vous pouvez créer des tests imbriqués au sein d'un test plus important. Cette méthode se comporte de manière identique à la fonction test() de niveau supérieur. L'exemple suivant illustre la création d'un test de niveau supérieur avec deux sous-tests.

js
test('test de niveau supérieur', async t => {
  await t.test('sous-test 1', t => {
    assert.strictEqual(1, 1)
  })

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

Dans cet exemple, await est utilisé pour s'assurer que les deux sous-tests sont terminés. Ceci est nécessaire car les tests n'attendent pas que leurs sous-tests se terminent, contrairement aux tests créés dans les suites. Tous les sous-tests qui sont encore en suspens lorsque leur parent se termine sont annulés et traités comme des échecs. Tous les échecs de sous-tests entraînent l'échec du test parent.

Ignorer les tests

Les tests individuels peuvent être ignorés en passant l'option skip au test, ou en appelant la méthode skip() du contexte de test comme indiqué dans l'exemple suivant.

js
// L'option skip est utilisée, mais aucun message n'est fourni.
test('option skip', { skip: true }, t => {
  // Ce code n'est jamais exécuté.
})

// L'option skip est utilisée, et un message est fourni.
test('option skip avec message', { skip: 'ceci est ignoré' }, t => {
  // Ce code n'est jamais exécuté.
})

test('méthode skip()', t => {
  // Assurez-vous également de revenir ici si le test contient une logique supplémentaire.
  t.skip()
})

test('méthode skip() avec message', t => {
  // Assurez-vous également de revenir ici si le test contient une logique supplémentaire.
  t.skip('ceci est ignoré')
})

Tests TODO

Les tests individuels peuvent être marqués comme instables ou incomplets en passant l'option todo au test, ou en appelant la méthode todo() du contexte de test, comme indiqué dans l'exemple suivant. Ces tests représentent une implémentation en attente ou un bug qui doit être corrigé. Les tests TODO sont exécutés, mais ne sont pas considérés comme des échecs de test, et n'affectent donc pas le code de sortie du processus. Si un test est marqué à la fois comme TODO et ignoré, l'option TODO est ignorée.

js
// L'option todo est utilisée, mais aucun message n'est fourni.
test('option todo', { todo: true }, (t) => {
  // Ce code est exécuté, mais n'est pas considéré comme un échec.
  throw new Error('ceci ne fait pas échouer le test');
});

// L'option todo est utilisée, et un message est fourni.
test('option todo avec message', { todo: 'ceci est un test todo' }, (t) => {
  // Ce code est exécuté.
});

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

test('méthode todo() avec message', (t) => {
  t.todo('ceci est un test todo et n'est pas considéré comme un échec');
  throw new Error('ceci ne fait pas échouer le test');
});

Alias describe() et it()

Les suites et les tests peuvent également être écrits à l'aide des fonctions describe() et it(). describe() est un alias pour suite(), et it() est un alias pour test().

js
describe('Une chose', () => {
  it('devrait fonctionner', () => {
    assert.strictEqual(1, 1)
  })

  it('devrait être ok', () => {
    assert.strictEqual(2, 2)
  })

  describe('une chose imbriquée', () => {
    it('devrait fonctionner', () => {
      assert.strictEqual(3, 3)
    })
  })
})

describe() et it() sont importés du module node:test.

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

Tests only

Si Node.js est démarré avec l'option de ligne de commande --test-only, ou que l'isolation des tests est désactivée, il est possible d'ignorer tous les tests à l'exception d'un sous-ensemble sélectionné en passant l'option only aux tests qui doivent être exécutés. Lorsqu'un test avec l'option only est défini, tous les sous-tests sont également exécutés. Si une suite a l'option only définie, tous les tests de la suite sont exécutés, sauf si elle a des descendants avec l'option only définie, auquel cas seuls ces tests sont exécutés.

Lorsque vous utilisez des sous-tests dans un test()/it(), il est nécessaire de marquer tous les tests ancêtres avec l'option only pour exécuter uniquement un sous-ensemble sélectionné de tests.

La méthode runOnly() du contexte de test peut être utilisée pour implémenter le même comportement au niveau du sous-test. Les tests qui ne sont pas exécutés sont omis de la sortie de l'exécuteur de tests.

js
// Supposons que Node.js est exécuté avec l'option de ligne de commande --test-only.
// L'option 'only' de la suite est définie, donc ces tests sont exécutés.
test('ce test est exécuté', { only: true }, async t => {
  // Dans ce test, tous les sous-tests sont exécutés par défaut.
  await t.test("sous-test en cours d'exécution")

  // Le contexte de test peut être mis à jour pour exécuter les sous-tests avec l'option 'only'.
  t.runOnly(true)
  await t.test('ce sous-test est maintenant ignoré')
  await t.test('ce sous-test est exécuté', { only: true })

  // Rétablissez le contexte pour exécuter tous les tests.
  t.runOnly(false)
  await t.test('ce sous-test est maintenant exécuté')

  // N'exécutez pas explicitement ces tests.
  await t.test('sous-test ignoré 3', { only: false })
  await t.test('sous-test ignoré 4', { skip: true })
})

// L'option 'only' n'est pas définie, donc ce test est ignoré.
test("ce test n'est pas exécuté", () => {
  // Ce code n'est pas exécuté.
  throw new Error('fail')
})

describe('une suite', () => {
  // L'option 'only' est définie, donc ce test est exécuté.
  it('ce test est exécuté', { only: true }, () => {
    // Ce code est exécuté.
  })

  it("ce test n'est pas exécuté", () => {
    // Ce code n'est pas exécuté.
    throw new Error('fail')
  })
})

describe.only('une suite', () => {
  // L'option 'only' est définie, donc ce test est exécuté.
  it('ce test est exécuté', () => {
    // Ce code est exécuté.
  })

  it('ce test est exécuté', () => {
    // Ce code est exécuté.
  })
})

Filtrer les tests par nom

L'option de ligne de commande --test-name-pattern peut être utilisée pour exécuter uniquement les tests dont le nom correspond au modèle fourni, et l'option --test-skip-pattern peut être utilisée pour ignorer les tests dont le nom correspond au modèle fourni. Les modèles de noms de test sont interprétés comme des expressions régulières JavaScript. Les options --test-name-pattern et --test-skip-pattern peuvent être spécifiées plusieurs fois afin d'exécuter des tests imbriqués. Pour chaque test exécuté, tous les hooks de test correspondants, tels que beforeEach(), sont également exécutés. Les tests qui ne sont pas exécutés sont omis de la sortie de l'exécuteur de tests.

Étant donné le fichier de test suivant, démarrer Node.js avec l'option --test-name-pattern="test [1-3]" entraînerait l'exécution par l'exécuteur de tests de test 1, test 2 et test 3. Si test 1 ne correspondait pas au modèle de nom de test, ses sous-tests ne seraient pas exécutés, même s'ils correspondaient au modèle. Le même ensemble de tests pourrait également être exécuté en passant --test-name-pattern plusieurs fois (par exemple, --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')
})

Les modèles de noms de test peuvent également être spécifiés à l'aide de littéraux d'expressions régulières. Cela permet d'utiliser des drapeaux d'expressions régulières. Dans l'exemple précédent, démarrer Node.js avec --test-name-pattern="/test [4-5]/i" (ou --test-skip-pattern="/test [4-5]/i") correspondrait à Test 4 et Test 5 car le modèle n'est pas sensible à la casse.

Pour faire correspondre un seul test avec un modèle, vous pouvez le préfixer avec tous les noms de tests ancêtres séparés par un espace, afin de vous assurer qu'il est unique. Par exemple, étant donné le fichier de test suivant :

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

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

Démarrer Node.js avec --test-name-pattern="test 1 some test" ne correspondrait qu'à some test dans test 1.

Les modèles de noms de test ne modifient pas l'ensemble des fichiers que l'exécuteur de tests exécute.

Si --test-name-pattern et --test-skip-pattern sont tous deux fournis, les tests doivent satisfaire les deux exigences pour être exécutés.

Activité asynchrone superflue

Une fois qu'une fonction de test a fini de s'exécuter, les résultats sont rapportés aussi rapidement que possible tout en maintenant l'ordre des tests. Cependant, il est possible que la fonction de test génère une activité asynchrone qui survit au test lui-même. Le lanceur de tests gère ce type d'activité, mais ne retarde pas le rapport des résultats des tests afin de s'en accommoder.

Dans l'exemple suivant, un test se termine avec deux opérations setImmediate() toujours en suspens. La première setImmediate() tente de créer un nouveau sous-test. Étant donné que le test parent est déjà terminé et a affiché ses résultats, le nouveau sous-test est immédiatement marqué comme ayant échoué et est rapporté ultérieurement au <TestsStream>.

La deuxième setImmediate() crée un événement uncaughtException. Les événements uncaughtException et unhandledRejection provenant d'un test terminé sont marqués comme ayant échoué par le module test et sont rapportés comme avertissements de diagnostic au niveau supérieur par le <TestsStream>.

js
test('un test qui crée une activité asynchrone', t => {
  setImmediate(() => {
    t.test('sous-test créé trop tard', t => {
      throw new Error('erreur1')
    })
  })

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

  // Le test se termine après cette ligne.
})

Mode surveillance

Ajouté dans : v19.2.0, v18.13.0

[Stable: 1 - Expérimental]

Stable: 1 Stabilité : 1 - Expérimental

Le lanceur de tests Node.js prend en charge l'exécution en mode surveillance en passant l'indicateur --watch:

bash
node --test --watch

En mode surveillance, le lanceur de tests surveillera les modifications apportées aux fichiers de test et à leurs dépendances. Lorsqu'une modification est détectée, le lanceur de tests réexécutera les tests affectés par la modification. Le lanceur de tests continuera de s'exécuter jusqu'à ce que le processus soit terminé.

Exécution des tests à partir de la ligne de commande

Le lanceur de tests Node.js peut être invoqué à partir de la ligne de commande en passant l'indicateur --test:

bash
node --test

Par défaut, Node.js exécutera tous les fichiers correspondant à ces modèles:

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

Lorsque --experimental-strip-types est fourni, les modèles supplémentaires suivants sont mis en correspondance:

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

Alternativement, un ou plusieurs modèles glob peuvent être fournis comme dernier(s) argument(s) à la commande Node.js, comme indiqué ci-dessous. Les modèles glob suivent le comportement de glob(7). Les modèles glob doivent être inclus entre guillemets doubles sur la ligne de commande pour éviter l'expansion du shell, ce qui peut réduire la portabilité entre les systèmes.

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

Les fichiers correspondants sont exécutés comme fichiers de test. Plus d'informations sur l'exécution des fichiers de test peuvent être trouvées dans la section modèle d'exécution du lanceur de tests.

Modèle d'exécution du lanceur de tests

Lorsque l'isolation des tests au niveau du processus est activée, chaque fichier de test correspondant est exécuté dans un processus enfant séparé. Le nombre maximal de processus enfants en cours d'exécution à tout moment est contrôlé par l'indicateur --test-concurrency. Si le processus enfant se termine avec un code de sortie de 0, le test est considéré comme réussi. Sinon, le test est considéré comme un échec. Les fichiers de test doivent être exécutables par Node.js, mais ne sont pas tenus d'utiliser le module node:test en interne.

Chaque fichier de test est exécuté comme s'il s'agissait d'un script ordinaire. C'est-à-dire que si le fichier de test lui-même utilise node:test pour définir des tests, tous ces tests seront exécutés dans un seul thread d'application, quelle que soit la valeur de l'option concurrency de test().

Lorsque l'isolation des tests au niveau du processus est désactivée, chaque fichier de test correspondant est importé dans le processus du lanceur de tests. Une fois que tous les fichiers de test ont été chargés, les tests de niveau supérieur sont exécutés avec une concurrence de un. Étant donné que les fichiers de test sont tous exécutés dans le même contexte, il est possible que les tests interagissent entre eux d'une manière qui n'est pas possible lorsque l'isolation est activée. Par exemple, si un test repose sur un état global, il est possible que cet état soit modifié par un test provenant d'un autre fichier.

Collecte de la couverture de code

[Stable: 1 - Expérimental]

Stable: 1 Stabilité : 1 - Expérimental

Lorsque Node.js est démarré avec l'indicateur de ligne de commande --experimental-test-coverage, la couverture de code est collectée et des statistiques sont rapportées une fois que tous les tests sont terminés. Si la variable d'environnement NODE_V8_COVERAGE est utilisée pour spécifier un répertoire de couverture de code, les fichiers de couverture V8 générés sont écrits dans ce répertoire. Les modules principaux de Node.js et les fichiers dans les répertoires node_modules/ ne sont, par défaut, pas inclus dans le rapport de couverture. Cependant, ils peuvent être explicitement inclus via l'indicateur --test-coverage-include. Par défaut, tous les fichiers de test correspondants sont exclus du rapport de couverture. Les exclusions peuvent être remplacées en utilisant l'indicateur --test-coverage-exclude. Si la couverture est activée, le rapport de couverture est envoyé à tous les rapporteurs de tests via l'événement 'test:coverage'.

La couverture peut être désactivée sur une série de lignes en utilisant la syntaxe de commentaire suivante :

js
/* node:coverage disable */
if (anAlwaysFalseCondition) {
  // Le code de cette branche ne sera jamais exécuté, mais les lignes sont ignorées à des fins
  // de couverture. Toutes les lignes suivant le commentaire « disable » sont ignorées
  // jusqu'à ce qu'un commentaire « enable » correspondant soit rencontré.
  console.log('ceci n’est jamais exécuté')
}
/* node:coverage enable */

La couverture peut également être désactivée pour un nombre spécifié de lignes. Après le nombre spécifié de lignes, la couverture sera automatiquement réactivée. Si le nombre de lignes n'est pas explicitement fourni, une seule ligne est ignorée.

js
/* node:coverage ignore next */
if (anAlwaysFalseCondition) {
  console.log('ceci n’est jamais exécuté')
}

/* node:coverage ignore next 3 */
if (anAlwaysFalseCondition) {
  console.log('ceci n’est jamais exécuté')
}

Rapporteurs de couverture

Les rapporteurs tap et spec afficheront un résumé des statistiques de couverture. Il existe également un rapporteur lcov qui générera un fichier lcov qui peut être utilisé comme rapport de couverture approfondi.

bash
node --test --experimental-test-coverage --test-reporter=lcov --test-reporter-destination=lcov.info
  • Aucun résultat de test n'est rapporté par ce rapporteur.
  • Ce rapporteur devrait idéalement être utilisé avec un autre rapporteur.

Simulation

Le module node:test prend en charge la simulation pendant les tests via un objet mock de niveau supérieur. L'exemple suivant crée un espion sur une fonction qui additionne deux nombres. L'espion est ensuite utilisé pour affirmer que la fonction a été appelée comme prévu.

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

test('espionne une fonction', () => {
  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)

  // Réinitialiser les simulations suivies globalement.
  mock.reset()
})
js
'use strict'
const assert = require('node:assert')
const { mock, test } = require('node:test')

test('espionne une fonction', () => {
  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)

  // Réinitialiser les simulations suivies globalement.
  mock.reset()
})

La même fonctionnalité de simulation est également exposée sur l'objet TestContext de chaque test. L'exemple suivant crée un espion sur une méthode d'objet à l'aide de l'API exposée sur le TestContext. L'avantage de la simulation via le contexte de test est que l'exécuteur de test restaurera automatiquement toutes les fonctionnalités simulées une fois le test terminé.

js
test("espionne une méthode d'objet", 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)
})

Minuteurs

La simulation de minuteurs est une technique couramment utilisée dans les tests logiciels pour simuler et contrôler le comportement des minuteurs, tels que setInterval et setTimeout, sans attendre réellement les intervalles de temps spécifiés.

Consultez la classe MockTimers pour une liste complète des méthodes et fonctionnalités.

Cela permet aux développeurs d'écrire des tests plus fiables et prévisibles pour les fonctionnalités dépendant du temps.

L'exemple ci-dessous montre comment simuler setTimeout. En utilisant .enable({ apis: ['setTimeout'] });, les fonctions setTimeout des modules node:timers et node:timers/promises, ainsi que du contexte global Node.js, seront simulées.

Remarque : La déstructuration de fonctions telles que import { setTimeout } from 'node:timers' n'est actuellement pas prise en charge par cette API.

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

test('simule setTimeout pour qu’il soit exécuté de manière synchrone sans avoir à attendre réellement', () => {
  const fn = mock.fn()

  // Choisissez éventuellement ce qu’il faut simuler
  mock.timers.enable({ apis: ['setTimeout'] })
  setTimeout(fn, 9999)
  assert.strictEqual(fn.mock.callCount(), 0)

  // Avancer dans le temps
  mock.timers.tick(9999)
  assert.strictEqual(fn.mock.callCount(), 1)

  // Réinitialiser les simulations suivies globalement.
  mock.timers.reset()

  // Si vous appelez reset sur une instance de simulation, cela réinitialisera également l’instance des minuteurs
  mock.reset()
})
js
const assert = require('node:assert')
const { mock, test } = require('node:test')

test('simule setTimeout pour qu’il soit exécuté de manière synchrone sans avoir à attendre réellement', () => {
  const fn = mock.fn()

  // Choisissez éventuellement ce qu’il faut simuler
  mock.timers.enable({ apis: ['setTimeout'] })
  setTimeout(fn, 9999)
  assert.strictEqual(fn.mock.callCount(), 0)

  // Avancer dans le temps
  mock.timers.tick(9999)
  assert.strictEqual(fn.mock.callCount(), 1)

  // Réinitialiser les simulations suivies globalement.
  mock.timers.reset()

  // Si vous appelez reset sur une instance de simulation, cela réinitialisera également l’instance des minuteurs
  mock.reset()
})

La même fonctionnalité de simulation est également exposée dans la propriété mock de l’objet TestContext de chaque test. L’avantage de la simulation via le contexte de test est que le lanceur de tests restaure automatiquement toutes les fonctionnalités de minuteurs simulées une fois le test terminé.

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

test('simule setTimeout pour qu’il soit exécuté de manière synchrone sans avoir à attendre réellement', context => {
  const fn = context.mock.fn()

  // Choisissez éventuellement ce qu’il faut simuler
  context.mock.timers.enable({ apis: ['setTimeout'] })
  setTimeout(fn, 9999)
  assert.strictEqual(fn.mock.callCount(), 0)

  // Avancer dans le temps
  context.mock.timers.tick(9999)
  assert.strictEqual(fn.mock.callCount(), 1)
})
js
const assert = require('node:assert')
const { test } = require('node:test')

test('simule setTimeout pour qu’il soit exécuté de manière synchrone sans avoir à attendre réellement', context => {
  const fn = context.mock.fn()

  // Choisissez éventuellement ce qu’il faut simuler
  context.mock.timers.enable({ apis: ['setTimeout'] })
  setTimeout(fn, 9999)
  assert.strictEqual(fn.mock.callCount(), 0)

  // Avancer dans le temps
  context.mock.timers.tick(9999)
  assert.strictEqual(fn.mock.callCount(), 1)
})

Dates

L'API des temporisateurs simulés permet également de simuler l'objet Date. Il s'agit d'une fonctionnalité utile pour tester les fonctionnalités dépendantes du temps, ou pour simuler les fonctions de calendrier internes telles que Date.now().

L'implémentation des dates fait également partie de la classe MockTimers. Consultez-la pour une liste complète des méthodes et des fonctionnalités.

Remarque : Les dates et les temporisateurs sont dépendants lorsqu'ils sont simulés ensemble. Cela signifie que si vous avez à la fois Date et setTimeout simulés, faire avancer le temps fera également avancer la date simulée, car ils simulent une seule horloge interne.

L'exemple ci-dessous montre comment simuler l'objet Date et obtenir la valeur actuelle de Date.now().

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

test('simule l’objet Date', context => {
  // Choisissez éventuellement ce qu’il faut simuler
  context.mock.timers.enable({ apis: ['Date'] })
  // Si aucune date initiale n’est spécifiée, la date initiale sera basée sur 0 dans l’epoch UNIX
  assert.strictEqual(Date.now(), 0)

  // Avancer dans le temps fera également avancer la date
  context.mock.timers.tick(9999)
  assert.strictEqual(Date.now(), 9999)
})
js
const assert = require('node:assert')
const { test } = require('node:test')

test('simule l’objet Date', context => {
  // Choisissez éventuellement ce qu’il faut simuler
  context.mock.timers.enable({ apis: ['Date'] })
  // Si aucune date initiale n’est spécifiée, la date initiale sera basée sur 0 dans l’epoch UNIX
  assert.strictEqual(Date.now(), 0)

  // Avancer dans le temps fera également avancer la date
  context.mock.timers.tick(9999)
  assert.strictEqual(Date.now(), 9999)
})

S'il n'y a pas d'epoch initial définie, la date initiale sera basée sur 0 dans l'epoch Unix. Il s'agit du 1er janvier 1970, 00:00:00 UTC. Vous pouvez définir une date initiale en passant une propriété now à la méthode .enable(). Cette valeur sera utilisée comme date initiale pour l'objet Date simulé. Il peut s'agir d'un entier positif ou d'un autre objet Date.

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

test('simule l’objet Date avec l’heure initiale', context => {
  // Choisissez éventuellement ce qu’il faut simuler
  context.mock.timers.enable({ apis: ['Date'], now: 100 })
  assert.strictEqual(Date.now(), 100)

  // Avancer dans le temps fera également avancer la date
  context.mock.timers.tick(200)
  assert.strictEqual(Date.now(), 300)
})
js
const assert = require('node:assert')
const { test } = require('node:test')

test('simule l’objet Date avec l’heure initiale', context => {
  // Choisissez éventuellement ce qu’il faut simuler
  context.mock.timers.enable({ apis: ['Date'], now: 100 })
  assert.strictEqual(Date.now(), 100)

  // Avancer dans le temps fera également avancer la date
  context.mock.timers.tick(200)
  assert.strictEqual(Date.now(), 300)
})

Vous pouvez utiliser la méthode .setTime() pour déplacer manuellement la date simulée à une autre heure. Cette méthode n'accepte qu'un entier positif.

Remarque : Cette méthode exécutera tous les temporisateurs simulés qui sont dans le passé par rapport à la nouvelle heure.

Dans l'exemple ci-dessous, nous définissons une nouvelle heure pour la date simulée.

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

test('définit l’heure d’un objet Date', context => {
  // Choisissez éventuellement ce qu’il faut simuler
  context.mock.timers.enable({ apis: ['Date'], now: 100 })
  assert.strictEqual(Date.now(), 100)

  // Avancer dans le temps fera également avancer la date
  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('définit l’heure d’un objet Date', context => {
  // Choisissez éventuellement ce qu’il faut simuler
  context.mock.timers.enable({ apis: ['Date'], now: 100 })
  assert.strictEqual(Date.now(), 100)

  // Avancer dans le temps fera également avancer la date
  context.mock.timers.setTime(1000)
  context.mock.timers.tick(200)
  assert.strictEqual(Date.now(), 1200)
})

Si vous avez un temporisateur configuré pour s'exécuter dans le passé, il sera exécuté comme si la méthode .tick() avait été appelée. Ceci est utile si vous souhaitez tester des fonctionnalités dépendantes du temps qui sont déjà dans le passé.

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

test('exécute les temporisateurs lorsque setTime passe des ticks', context => {
  // Choisissez éventuellement ce qu’il faut simuler
  context.mock.timers.enable({ apis: ['setTimeout', 'Date'] })
  const fn = context.mock.fn()
  setTimeout(fn, 1000)

  context.mock.timers.setTime(800)
  // Le temporisateur n'est pas exécuté car le temps n'est pas encore atteint
  assert.strictEqual(fn.mock.callCount(), 0)
  assert.strictEqual(Date.now(), 800)

  context.mock.timers.setTime(1200)
  // Le temporisateur est exécuté car le temps est maintenant atteint
  assert.strictEqual(fn.mock.callCount(), 1)
  assert.strictEqual(Date.now(), 1200)
})
js
const assert = require('node:assert')
const { test } = require('node:test')

test('exécute les temporisateurs lorsque setTime passe des ticks', context => {
  // Choisissez éventuellement ce qu’il faut simuler
  context.mock.timers.enable({ apis: ['setTimeout', 'Date'] })
  const fn = context.mock.fn()
  setTimeout(fn, 1000)

  context.mock.timers.setTime(800)
  // Le temporisateur n'est pas exécuté car le temps n'est pas encore atteint
  assert.strictEqual(fn.mock.callCount(), 0)
  assert.strictEqual(Date.now(), 800)

  context.mock.timers.setTime(1200)
  // Le temporisateur est exécuté car le temps est maintenant atteint
  assert.strictEqual(fn.mock.callCount(), 1)
  assert.strictEqual(Date.now(), 1200)
})

L'utilisation de .runAll() exécutera tous les temporisateurs qui sont actuellement dans la file d'attente. Cela fera également avancer la date simulée à l'heure du dernier temporisateur qui a été exécuté, comme si le temps avait passé.

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

test('exécute les temporisateurs lorsque setTime passe des ticks', context => {
  // Choisissez éventuellement ce qu’il faut simuler
  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()
  // Tous les temporisateurs sont exécutés car le temps est maintenant atteint
  assert.strictEqual(fn.mock.callCount(), 3)
  assert.strictEqual(Date.now(), 3000)
})
js
const assert = require('node:assert')
const { test } = require('node:test')

test('exécute les temporisateurs lorsque setTime passe des ticks', context => {
  // Choisissez éventuellement ce qu’il faut simuler
  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()
  // Tous les temporisateurs sont exécutés car le temps est maintenant atteint
  assert.strictEqual(fn.mock.callCount(), 3)
  assert.strictEqual(Date.now(), 3000)
})

Tests instantanés

[Stable: 1 - Expérimental]

Stable: 1 Stabilité: 1.0 - Développement précoce

Les tests instantanés permettent de sérialiser des valeurs arbitraires en chaînes de caractères et de les comparer à un ensemble de valeurs de référence valides. Les valeurs de référence valides sont appelées instantanés et sont stockées dans un fichier d'instantané. Les fichiers d'instantané sont gérés par l'exécuteur de tests, mais sont conçus pour être lisibles par l'homme afin de faciliter le débogage. Il est recommandé de vérifier les fichiers d'instantané dans le contrôle de source en même temps que vos fichiers de test.

Les fichiers d'instantané sont générés en démarrant Node.js avec l'indicateur de ligne de commande --test-update-snapshots. Un fichier d'instantané distinct est généré pour chaque fichier de test. Par défaut, le fichier d'instantané porte le même nom que le fichier de test avec l'extension .snapshot. Ce comportement peut être configuré à l'aide de la fonction snapshot.setResolveSnapshotPath(). Chaque assertion d'instantané correspond à une exportation dans le fichier d'instantané.

Un exemple de test d'instantané est présenté ci-dessous. La première fois que ce test est exécuté, il échouera car le fichier d'instantané correspondant n'existe pas.

js
// test.js
suite('suite de tests instantanés', () => {
  test('test d'instantané', (t) => {
    t.assert.snapshot({ value1: 1, value2: 2 });
    t.assert.snapshot(5);
  });
});

Générez le fichier d'instantané en exécutant le fichier de test avec --test-update-snapshots. Le test devrait réussir et un fichier nommé test.js.snapshot est créé dans le même répertoire que le fichier de test. Le contenu du fichier d'instantané est présenté ci-dessous. Chaque instantané est identifié par le nom complet du test et un compteur pour différencier les instantanés dans le même test.

js
exports[`suite de tests instantanés > test d'instantané 1`] = `
{
  "value1": 1,
  "value2": 2
}
`

exports[`suite de tests instantanés > test d'instantané 2`] = `
5
`

Une fois le fichier d'instantané créé, exécutez à nouveau les tests sans l'indicateur --test-update-snapshots. Les tests devraient maintenant réussir.

Rapporteurs de test

[Historique]

VersionChangements
v19.9.0, v18.17.0Les rapporteurs sont désormais exposés dans node:test/reporters.
v19.6.0, v18.15.0Ajouté dans : v19.6.0, v18.15.0

Le module node:test prend en charge le passage d'indicateurs --test-reporter pour que le lanceur de tests utilise un rapporteur spécifique.

Les rapporteurs intégrés suivants sont pris en charge :

  • spec Le rapporteur spec affiche les résultats des tests dans un format lisible par l'homme. C'est le rapporteur par défaut.
  • tap Le rapporteur tap affiche les résultats des tests au format TAP.
  • dot Le rapporteur dot affiche les résultats des tests dans un format compact, où chaque test réussi est représenté par un ., et chaque test échoué est représenté par un X.
  • junit Le rapporteur junit affiche les résultats des tests au format XML jUnit.
  • lcov Le rapporteur lcov affiche la couverture de test lorsqu'il est utilisé avec l'indicateur --experimental-test-coverage.

La sortie exacte de ces rapporteurs est susceptible de changer entre les versions de Node.js, et ne doit pas être utilisée de manière programmatique. Si un accès programmatique à la sortie du lanceur de tests est nécessaire, utilisez les événements émis par le <TestsStream>.

Les rapporteurs sont disponibles via le module 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')

Rapporteurs personnalisés

--test-reporter peut être utilisé pour spécifier un chemin d'accès à un rapporteur personnalisé. Un rapporteur personnalisé est un module qui exporte une valeur acceptée par stream.compose. Les rapporteurs doivent transformer les événements émis par un <TestsStream>.

Exemple de rapporteur personnalisé utilisant <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} mis en file d'attente`);
        break;
      case 'test:enqueue':
        callback(null, `test ${event.data.name} en file d'attente`);
        break;
      case 'test:watch:drained':
        callback(null, 'file d'attente de surveillance de test épuisée');
        break;
      case 'test:start':
        callback(null, `test ${event.data.name} démarré`);
        break;
      case 'test:pass':
        callback(null, `test ${event.data.name} réussi`);
        break;
      case 'test:fail':
        callback(null, `test ${event.data.name} échoué`);
        break;
      case 'test:plan':
        callback(null, 'plan de test');
        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, `nombre total de lignes : ${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} mis en file d'attente`);
        break;
      case 'test:enqueue':
        callback(null, `test ${event.data.name} en file d'attente`);
        break;
      case 'test:watch:drained':
        callback(null, 'file d'attente de surveillance de test épuisée');
        break;
      case 'test:start':
        callback(null, `test ${event.data.name} démarré`);
        break;
      case 'test:pass':
        callback(null, `test ${event.data.name} réussi`);
        break;
      case 'test:fail':
        callback(null, `test ${event.data.name} échoué`);
        break;
      case 'test:plan':
        callback(null, 'plan de test');
        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, `nombre total de lignes : ${totalLineCount}\n`);
        break;
      }
    }
  },
});

module.exports = customReporter;

Exemple de rapporteur personnalisé utilisant une fonction générateur :

js
export default async function* customReporter(source) {
  for await (const event of source) {
    switch (event.type) {
      case 'test:dequeue':
        yield `test ${event.data.name} mis en file d'attente\n`
        break
      case 'test:enqueue':
        yield `test ${event.data.name} en file d'attente\n`
        break
      case 'test:watch:drained':
        yield "file d'attente de surveillance de test épuisée\n"
        break
      case 'test:start':
        yield `test ${event.data.name} démarré\n`
        break
      case 'test:pass':
        yield `test ${event.data.name} réussi\n`
        break
      case 'test:fail':
        yield `test ${event.data.name} échoué\n`
        break
      case 'test:plan':
        yield 'plan de test\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 `nombre total de lignes : ${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} mis en file d'attente\n`
        break
      case 'test:enqueue':
        yield `test ${event.data.name} en file d'attente\n`
        break
      case 'test:watch:drained':
        yield "file d'attente de surveillance de test épuisée\n"
        break
      case 'test:start':
        yield `test ${event.data.name} démarré\n`
        break
      case 'test:pass':
        yield `test ${event.data.name} réussi\n`
        break
      case 'test:fail':
        yield `test ${event.data.name} échoué\n`
        break
      case 'test:plan':
        yield 'plan de test\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 `nombre total de lignes : ${totalLineCount}\n`
        break
      }
    }
  }
}

La valeur fournie à --test-reporter doit être une chaîne de caractères comme celle utilisée dans un import() dans le code JavaScript, ou une valeur fournie pour --import.

Plusieurs rapporteurs

L'option --test-reporter peut être spécifiée plusieurs fois pour générer des rapports de résultats de test dans plusieurs formats. Dans ce cas, il est nécessaire de spécifier une destination pour chaque rapporteur en utilisant --test-reporter-destination. La destination peut être stdout, stderr ou un chemin de fichier. Les rapporteurs et les destinations sont associés en fonction de l'ordre dans lequel ils ont été spécifiés.

Dans l'exemple suivant, le rapporteur spec affichera ses résultats sur stdout, et le rapporteur dot les affichera dans file.txt :

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

Lorsqu'un seul rapporteur est spécifié, la destination par défaut sera stdout, sauf si une destination est explicitement fournie.

run([options])

[Historique]

VersionModifications
v23.0.0Ajout de l'option cwd.
v23.0.0Ajout des options de couverture.
v22.8.0Ajout de l'option isolation.
v22.6.0Ajout de l'option globPatterns.
v22.0.0, v20.14.0Ajout de l'option forceExit.
v20.1.0, v18.17.0Ajout de l'option testNamePatterns.
v18.9.0, v16.19.0Ajout dans : v18.9.0, v16.19.0
  • options <Object> Options de configuration pour l'exécution des tests. Les propriétés suivantes sont prises en charge :

    • concurrency <number> | <boolean> Si un nombre est fourni, ce nombre de processus de test s'exécutera en parallèle, chaque processus correspondant à un fichier de test. Si true, os.availableParallelism() - 1 fichiers de test s'exécuteront en parallèle. Si false, un seul fichier de test s'exécutera à la fois. Par défaut : false.

    • cwd : <string> Spécifie le répertoire de travail actuel à utiliser par le lanceur de tests. Sert de chemin de base pour la résolution des fichiers conformément au modèle d'exécution du lanceur de tests. Par défaut : process.cwd().

    • files : <Array> Un tableau contenant la liste des fichiers à exécuter. Par défaut : fichiers correspondants du modèle d'exécution du lanceur de tests.

    • forceExit : <boolean> Configure le lanceur de tests pour quitter le processus une fois que tous les tests connus ont fini de s'exécuter, même si la boucle d'événements resterait active dans le cas contraire. Par défaut : false.

    • globPatterns : <Array> Un tableau contenant la liste des modèles globaux pour correspondre aux fichiers de test. Cette option ne peut pas être utilisée conjointement avec files. Par défaut : fichiers correspondants du modèle d'exécution du lanceur de tests.

    • inspectPort <number> | <Function> Définit le port de l'inspecteur du processus enfant de test. Il peut s'agir d'un nombre ou d'une fonction qui ne prend aucun argument et renvoie un nombre. Si une valeur nulle est fournie, chaque processus reçoit son propre port, incrémenté à partir du process.debugPort du processus principal. Cette option est ignorée si l'option isolation est définie sur 'none' car aucun processus enfant n'est généré. Par défaut : undefined.

    • isolation <string> Configure le type d'isolation des tests. Si la valeur est définie sur 'process', chaque fichier de test est exécuté dans un processus enfant distinct. Si la valeur est définie sur 'none', tous les fichiers de test sont exécutés dans le processus actuel. Par défaut : 'process'.

    • only : <boolean> Si la valeur est true, le contexte de test n'exécutera que les tests qui ont l'option only définie.

    • setup <Function> Une fonction qui accepte l'instance TestsStream et qui peut être utilisée pour configurer des écouteurs avant l'exécution de tout test. Par défaut : undefined.

    • execArgv <Array> Un tableau de drapeaux CLI à passer à l'exécutable node lors de la création des sous-processus. Cette option n'a aucun effet lorsque isolation est 'none'. Par défaut : []

    • argv <Array> Un tableau de drapeaux CLI à passer à chaque fichier de test lors de la création des sous-processus. Cette option n'a aucun effet lorsque isolation est 'none'. Par défaut : [].

    • signal <AbortSignal> Permet d'interrompre une exécution de test en cours.

    • testNamePatterns <string> | <RegExp> | <Array> Une chaîne, une RegExp ou un tableau de RegExp, qui peuvent être utilisés pour n'exécuter que les tests dont le nom correspond au modèle fourni. Les modèles de noms de test sont interprétés comme des expressions régulières JavaScript. Pour chaque test exécuté, tous les hooks de test correspondants, tels que beforeEach(), sont également exécutés. Par défaut : undefined.

    • testSkipPatterns <string> | <RegExp> | <Array> Une chaîne, une RegExp ou un tableau de RegExp, qui peuvent être utilisés pour exclure l'exécution des tests dont le nom correspond au modèle fourni. Les modèles de noms de test sont interprétés comme des expressions régulières JavaScript. Pour chaque test exécuté, tous les hooks de test correspondants, tels que beforeEach(), sont également exécutés. Par défaut : undefined.

    • timeout <number> Nombre de millisecondes après lequel l'exécution du test échouera. S'il n'est pas spécifié, les sous-tests héritent de cette valeur de leur parent. Par défaut : Infinity.

    • watch <boolean> Indique s'il faut exécuter en mode surveillance ou non. Par défaut : false.

    • shard <Object> Exécution de tests dans un shard spécifique. Par défaut : undefined.

      • index <number> est un entier positif compris entre 1 et \<total\> qui spécifie l'index du shard à exécuter. Cette option est obligatoire.
      • total <number> est un entier positif qui spécifie le nombre total de shards dans lesquels diviser les fichiers de test. Cette option est obligatoire.
    • coverage <boolean> active la collecte de la couverture du code. Par défaut : false.

    • coverageExcludeGlobs <string> | <Array> Exclut des fichiers spécifiques de la couverture du code en utilisant un modèle glob, qui peut correspondre à des chemins de fichiers absolus et relatifs. Cette propriété n'est applicable que lorsque coverage a été défini sur true. Si coverageExcludeGlobs et coverageIncludeGlobs sont tous les deux fournis, les fichiers doivent remplir les deux critères pour être inclus dans le rapport de couverture. Par défaut : undefined.

    • coverageIncludeGlobs <string> | <Array> Inclut des fichiers spécifiques dans la couverture du code en utilisant un modèle glob, qui peut correspondre à des chemins de fichiers absolus et relatifs. Cette propriété n'est applicable que lorsque coverage a été défini sur true. Si coverageExcludeGlobs et coverageIncludeGlobs sont tous les deux fournis, les fichiers doivent remplir les deux critères pour être inclus dans le rapport de couverture. Par défaut : undefined.

    • lineCoverage <number> Exige un pourcentage minimum de lignes couvertes. Si la couverture du code n'atteint pas le seuil spécifié, le processus se termine avec le code 1. Par défaut : 0.

    • branchCoverage <number> Exige un pourcentage minimum de branches couvertes. Si la couverture du code n'atteint pas le seuil spécifié, le processus se termine avec le code 1. Par défaut : 0.

    • functionCoverage <number> Exige un pourcentage minimum de fonctions couvertes. Si la couverture du code n'atteint pas le seuil spécifié, le processus se termine avec le code 1. Par défaut : 0.

  • Renvoie : <TestsStream>

Remarque : shard est utilisé pour paralléliser horizontalement l'exécution des tests sur plusieurs machines ou processus, ce qui est idéal pour les exécutions à grande échelle dans différents environnements. Il est incompatible avec le mode watch, conçu pour une itération rapide du code en réexécutant automatiquement les tests lors des modifications de fichiers.

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])

Ajouté dans : v22.0.0, v20.13.0

  • name <string> Le nom de la suite, qui est affiché lors de la communication des résultats des tests. Par défaut : La propriété name de fn, ou '\<anonymous\>' si fn n’a pas de nom.
  • options <Object> Options de configuration facultatives pour la suite. Prend en charge les mêmes options que test([name][, options][, fn]).
  • fn <Function> | <AsyncFunction> La fonction de suite qui déclare des tests et des suites imbriqués. Le premier argument de cette fonction est un objet SuiteContext. Par défaut : Une fonction sans opération.
  • Renvoie : <Promise> Immédiatement remplie avec undefined.

La fonction suite() est importée à partir du module node:test.

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

Ajouté dans : v22.0.0, v20.13.0

Raccourci pour ignorer une suite. Cela est identique à suite([name], { skip: true }[, fn]).

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

Ajouté dans : v22.0.0, v20.13.0

Raccourci pour marquer une suite comme TODO. Cela est identique à suite([name], { todo: true }[, fn]).

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

Ajouté dans : v22.0.0, v20.13.0

Raccourci pour marquer une suite comme only. Cela est identique à suite([name], { only: true }[, fn]).

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

[Historique]

VersionChangements
v20.2.0, v18.17.0Ajout des raccourcis skip, todo et only.
v18.8.0, v16.18.0Ajout d’une option signal.
v18.7.0, v16.17.0Ajout d’une option timeout.
v18.0.0, v16.17.0Ajouté dans : v18.0.0, v16.17.0
  • name <string> Le nom du test, qui est affiché lors de la communication des résultats des tests. Par défaut : La propriété name de fn, ou '\<anonymous\>' si fn n’a pas de nom.

  • options <Object> Options de configuration pour le test. Les propriétés suivantes sont prises en charge :

    • concurrency <number> | <boolean> Si un nombre est fourni, ce nombre de tests s’exécute en parallèle dans le thread d’application. Si true, tous les tests asynchrones planifiés s’exécutent simultanément dans le thread. Si false, un seul test s’exécute à la fois. S’il n’est pas spécifié, les sous-tests héritent de cette valeur de leur parent. Par défaut : false.
    • only <boolean> Si la valeur est véridique et que le contexte de test est configuré pour exécuter les tests only, ce test sera exécuté. Sinon, le test est ignoré. Par défaut : false.
    • signal <AbortSignal> Permet d’abandonner un test en cours.
    • skip <boolean> | <string> Si la valeur est véridique, le test est ignoré. Si une chaîne est fournie, cette chaîne est affichée dans les résultats du test comme raison de l’ignorance du test. Par défaut : false.
    • todo <boolean> | <string> Si la valeur est véridique, le test est marqué comme TODO. Si une chaîne est fournie, cette chaîne est affichée dans les résultats du test comme raison pour laquelle le test est TODO. Par défaut : false.
    • timeout <number> Un nombre de millisecondes après lequel le test échouera. S’il n’est pas spécifié, les sous-tests héritent de cette valeur de leur parent. Par défaut : Infinity.
    • plan <number> Le nombre d’assertions et de sous-tests qui doivent être exécutés dans le test. Si le nombre d’assertions exécutées dans le test ne correspond pas au nombre spécifié dans le plan, le test échouera. Par défaut : undefined.
  • fn <Function> | <AsyncFunction> La fonction testée. Le premier argument de cette fonction est un objet TestContext. Si le test utilise des rappels, la fonction de rappel est passée comme deuxième argument. Par défaut : Une fonction sans opération.

  • Renvoie : <Promise> Remplie avec undefined une fois le test terminé, ou immédiatement si le test s’exécute dans une suite.

La fonction test() est la valeur importée du module test. Chaque invocation de cette fonction entraîne la communication du test au <TestsStream>.

L’objet TestContext passé à l’argument fn peut être utilisé pour effectuer des actions liées au test actuel. Citons par exemple l’ignorance du test, l’ajout d’informations de diagnostic supplémentaires ou la création de sous-tests.

test() renvoie une Promise qui est remplie une fois le test terminé. Si test() est appelé dans une suite, il est rempli immédiatement. La valeur de retour peut généralement être ignorée pour les tests de niveau supérieur. Toutefois, la valeur de retour des sous-tests doit être utilisée pour empêcher le test parent de se terminer en premier et d’annuler le sous-test comme indiqué dans l’exemple suivant.

js
test('test de niveau supérieur', async t => {
  // Le setTimeout() dans le sous-test suivant l’amènerait à survivre à son
  // test parent si 'await' est supprimé sur la ligne suivante. Une fois le test parent
  // terminé, il annulera tous les sous-tests en suspens.
  await t.test('sous-test de plus longue durée', async t => {
    return new Promise((resolve, reject) => {
      setTimeout(resolve, 1000)
    })
  })
})

L’option timeout peut être utilisée pour faire échouer le test s’il prend plus de timeout millisecondes pour se terminer. Cependant, il ne s’agit pas d’un mécanisme fiable pour annuler les tests, car un test en cours peut bloquer le thread d’application et donc empêcher l’annulation planifiée.

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

Raccourci pour ignorer un test, identique à test([name], { skip: true }[, fn]).

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

Raccourci pour marquer un test comme TODO, identique à test([name], { todo: true }[, fn]).

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

Raccourci pour marquer un test comme only, identique à test([name], { only: true }[, fn]).

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

Alias pour suite().

La fonction describe() est importée du module node:test.

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

Raccourci pour ignorer une suite. C'est la même chose que describe([name], { skip: true }[, fn]).

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

Raccourci pour marquer une suite comme TODO. C'est la même chose que describe([name], { todo: true }[, fn]).

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

Ajouté dans : v19.8.0, v18.15.0

Raccourci pour marquer une suite comme only. C'est la même chose que describe([name], { only: true }[, fn]).

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

[Historique]

VersionModifications
v19.8.0, v18.16.0L'appel à it() équivaut désormais à l'appel à test().
v18.6.0, v16.17.0Ajouté dans : v18.6.0, v16.17.0

Alias pour test().

La fonction it() est importée du module node:test.

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

Raccourci pour ignorer un test, identique à it([name], { skip: true }[, fn]).

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

Raccourci pour marquer un test comme TODO, identique à it([name], { todo: true }[, fn]).

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

Ajouté dans : v19.8.0, v18.15.0

Raccourci pour marquer un test comme only, identique à it([name], { only: true }[, fn]).

before([fn][, options])

Ajouté dans : v18.8.0, v16.18.0

  • fn <Function> | <AsyncFunction> La fonction de hook. Si le hook utilise des callbacks, la fonction de callback est passée comme second argument. Par défaut : une fonction no-op.
  • options <Object> Options de configuration pour le hook. Les propriétés suivantes sont prises en charge :
    • signal <AbortSignal> Permet d'annuler un hook en cours.
    • timeout <number> Le nombre de millisecondes après lesquelles le hook échouera. Si non spécifié, les sous-tests héritent de cette valeur de leur parent. Par défaut : Infinity.

Cette fonction crée un hook qui s'exécute avant l'exécution d'une suite.

js
describe('tests', async () => {
  before(() => console.log('about to run some test'))
  it('is a subtest', () => {
    assert.ok('some relevant assertion here')
  })
})

after([fn][, options])

Ajouté dans : v18.8.0, v16.18.0

  • fn <Function> | <AsyncFunction> La fonction de hook. Si le hook utilise des callbacks, la fonction de callback est passée comme second argument. Par défaut : une fonction no-op.
  • options <Object> Options de configuration pour le hook. Les propriétés suivantes sont prises en charge :
    • signal <AbortSignal> Permet d'annuler un hook en cours.
    • timeout <number> Le nombre de millisecondes après lesquelles le hook échouera. Si non spécifié, les sous-tests héritent de cette valeur de leur parent. Par défaut : Infinity.

Cette fonction crée un hook qui s'exécute après l'exécution d'une suite.

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

Note : Le hook after est garanti de s'exécuter, même si les tests au sein de la suite échouent.

beforeEach([fn][, options])

Ajouté dans : v18.8.0, v16.18.0

  • fn <Function> | <AsyncFunction> La fonction de hook. Si le hook utilise des rappels, la fonction de rappel est passée comme deuxième argument. Par défaut : une fonction no-op.
  • options <Object> Options de configuration pour le hook. Les propriétés suivantes sont prises en charge :
    • signal <AbortSignal> Permet d’abandonner un hook en cours.
    • timeout <number> Nombre de millisecondes après lequel le hook échouera. Si aucune valeur n’est spécifiée, les sous-tests héritent de cette valeur de leur parent. Par défaut : Infinity.

Cette fonction crée un hook qui s’exécute avant chaque test de la suite actuelle.

js
describe('tests', async () => {
  beforeEach(() => console.log('sur le point d’exécuter un test'))
  it('est un sous-test', () => {
    assert.ok('une assertion pertinente ici')
  })
})

afterEach([fn][, options])

Ajouté dans : v18.8.0, v16.18.0

  • fn <Function> | <AsyncFunction> La fonction de hook. Si le hook utilise des rappels, la fonction de rappel est passée comme deuxième argument. Par défaut : une fonction no-op.
  • options <Object> Options de configuration pour le hook. Les propriétés suivantes sont prises en charge :
    • signal <AbortSignal> Permet d’abandonner un hook en cours.
    • timeout <number> Nombre de millisecondes après lequel le hook échouera. Si aucune valeur n’est spécifiée, les sous-tests héritent de cette valeur de leur parent. Par défaut : Infinity.

Cette fonction crée un hook qui s’exécute après chaque test de la suite actuelle. Le hook afterEach() s’exécute même si le test échoue.

js
describe('tests', async () => {
  afterEach(() => console.log('fin de l’exécution d’un test'))
  it('est un sous-test', () => {
    assert.ok('une assertion pertinente ici')
  })
})

snapshot

Ajouté dans : v22.3.0

[Stable: 1 - Expérimental]

Stable: 1 Stabilité : 1.0 - Développement précoce

Un objet dont les méthodes sont utilisées pour configurer les paramètres d'instantané par défaut dans le processus actuel. Il est possible d'appliquer la même configuration à tous les fichiers en plaçant le code de configuration commun dans un module préchargé avec --require ou --import.

snapshot.setDefaultSnapshotSerializers(serializers)

Ajouté dans : v22.3.0

[Stable: 1 - Expérimental]

Stable: 1 Stabilité : 1.0 - Développement précoce

  • serializers <Array> Un tableau de fonctions synchrones utilisées comme sérialiseurs par défaut pour les tests d'instantané.

Cette fonction est utilisée pour personnaliser le mécanisme de sérialisation par défaut utilisé par l'exécuteur de tests. Par défaut, l'exécuteur de tests effectue la sérialisation en appelant JSON.stringify(value, null, 2) sur la valeur fournie. JSON.stringify() a des limitations concernant les structures circulaires et les types de données pris en charge. Si un mécanisme de sérialisation plus robuste est nécessaire, cette fonction doit être utilisée.

snapshot.setResolveSnapshotPath(fn)

Ajouté dans : v22.3.0

[Stable: 1 - Expérimental]

Stable: 1 Stabilité : 1.0 - Développement précoce

  • fn <Function> Une fonction utilisée pour calculer l'emplacement du fichier d'instantané. La fonction reçoit le chemin du fichier de test comme seul argument. Si le test n'est pas associé à un fichier (par exemple dans le REPL), l'entrée est indéfinie. fn() doit renvoyer une chaîne spécifiant l'emplacement du fichier d'instantané.

Cette fonction est utilisée pour personnaliser l'emplacement du fichier d'instantané utilisé pour les tests d'instantané. Par défaut, le nom du fichier d'instantané est le même que le nom du fichier de point d'entrée avec une extension de fichier .snapshot.

Classe : MockFunctionContext

Ajoutée dans : v19.1.0, v18.13.0

La classe MockFunctionContext est utilisée pour inspecter ou manipuler le comportement des mocks créés via les API MockTracker.

ctx.calls

Ajoutée dans : v19.1.0, v18.13.0

Un getter qui renvoie une copie du tableau interne utilisé pour suivre les appels au mock. Chaque entrée du tableau est un objet avec les propriétés suivantes.

  • arguments <Array> Un tableau des arguments passés à la fonction mock.
  • error <any> Si la fonction simulée a levé une exception, cette propriété contient la valeur levée. Par défaut : undefined.
  • result <any> La valeur renvoyée par la fonction simulée.
  • stack <Error> Un objet Error dont la pile peut être utilisée pour déterminer le site d'appel de l'invocation de la fonction simulée.
  • target <Function> | <undefined> Si la fonction simulée est un constructeur, ce champ contient la classe en cours de construction. Sinon, ce sera undefined.
  • this <any> La valeur this de la fonction simulée.

ctx.callCount()

Ajoutée dans : v19.1.0, v18.13.0

  • Retourne : <integer> Le nombre de fois où ce mock a été invoqué.

Cette fonction renvoie le nombre de fois où ce mock a été invoqué. Cette fonction est plus efficace que de vérifier ctx.calls.length car ctx.calls est un getter qui crée une copie du tableau interne de suivi des appels.

ctx.mockImplementation(implementation)

Ajouté dans : v19.1.0, v18.13.0

Cette fonction est utilisée pour modifier le comportement d'un mock existant.

L'exemple suivant crée une fonction mock en utilisant t.mock.fn(), appelle la fonction mock, puis modifie l'implémentation du mock en une fonction différente.

js
test('modifie le comportement d’un mock', 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])

Ajouté dans : v19.1.0, v18.13.0

  • implementation <Function> | <AsyncFunction> La fonction à utiliser comme implémentation du mock pour le numéro d'invocation spécifié par onCall.
  • onCall <integer> Le numéro d'invocation qui utilisera implementation. Si l'invocation spécifiée a déjà eu lieu, une exception est levée. Par défaut : Le numéro de la prochaine invocation.

Cette fonction est utilisée pour modifier le comportement d'un mock existant pour une seule invocation. Une fois que l'invocation onCall a eu lieu, le mock revient au comportement qu'il aurait eu si mockImplementationOnce() n'avait pas été appelé.

L'exemple suivant crée une fonction mock en utilisant t.mock.fn(), appelle la fonction mock, modifie l'implémentation du mock en une fonction différente pour la prochaine invocation, puis reprend son comportement précédent.

js
test('modifie le comportement d’un mock une seule fois', 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()

Ajouté dans : v19.3.0, v18.13.0

Réinitialise l’historique des appels de la fonction simulée.

ctx.restore()

Ajouté dans : v19.1.0, v18.13.0

Réinitialise l’implémentation de la fonction simulée à son comportement d’origine. La simulation peut toujours être utilisée après l’appel de cette fonction.

Classe : MockModuleContext

Ajouté dans : v22.3.0, v20.18.0

[Stable: 1 - Expérimental]

Stable : 1 Stable : 1.0 - Développement initial

La classe MockModuleContext est utilisée pour manipuler le comportement des simulations de modules créées via les API MockTracker.

ctx.restore()

Ajouté dans : v22.3.0, v20.18.0

Réinitialise l’implémentation du module simulé.

Classe : MockTracker

Ajouté dans : v19.1.0, v18.13.0

La classe MockTracker est utilisée pour gérer la fonctionnalité de simulation. Le module de l’exécuteur de tests fournit une exportation mock de niveau supérieur qui est une instance MockTracker. Chaque test fournit également sa propre instance MockTracker via la propriété mock du contexte de test.

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

Ajouté dans : v19.1.0, v18.13.0

  • original <Function> | <AsyncFunction> Une fonction optionnelle sur laquelle créer une simulation. Par défaut : une fonction no-op.

  • implementation <Function> | <AsyncFunction> Une fonction optionnelle utilisée comme implémentation de la simulation pour original. Ceci est utile pour créer des simulations qui présentent un comportement pour un nombre spécifié d’appels, puis pour restaurer le comportement de original. Par défaut : la fonction spécifiée par original.

  • options <Object> Options de configuration optionnelles pour la fonction simulée. Les propriétés suivantes sont prises en charge :

    • times <integer> Le nombre de fois où la simulation utilisera le comportement de implementation. Une fois que la fonction simulée a été appelée times fois, elle restaurera automatiquement le comportement de original. Cette valeur doit être un entier supérieur à zéro. Par défaut : Infinity.
  • Retourne : <Proxy> La fonction simulée. La fonction simulée contient une propriété spéciale mock, qui est une instance de MockFunctionContext, et peut être utilisée pour inspecter et modifier le comportement de la fonction simulée.

Cette fonction est utilisée pour créer une fonction simulée.

L’exemple suivant crée une fonction simulée qui incrémente un compteur de un à chaque invocation. L’option times est utilisée pour modifier le comportement de la simulation de sorte que les deux premières invocations ajoutent deux au compteur au lieu de un.

js
test('simule une fonction de comptage', 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(objet, methodName[, implémentation][, options])

Ajouté dans : v19.3.0, v18.13.0

Cette fonction est un sucre syntaxique pour MockTracker.method avec options.getter défini sur true.

mock.method(objet, methodName[, implémentation][, options])

Ajouté dans : v19.1.0, v18.13.0

  • objet <Object> L'objet dont la méthode est en cours de simulation.

  • methodName <string> | <symbol> L'identifiant de la méthode sur objet à simuler. Si objet[methodName] n'est pas une fonction, une erreur est levée.

  • implémentation <Function> | <AsyncFunction> Une fonction optionnelle utilisée comme implémentation simulée pour objet[methodName]. Par défaut : La méthode originale spécifiée par objet[methodName].

  • options <Object> Options de configuration facultatives pour la méthode simulée. Les propriétés suivantes sont prises en charge :

    • getter <boolean> Si true, objet[methodName] est traitée comme un getter. Cette option ne peut pas être utilisée avec l'option setter. Par défaut : false.
    • setter <boolean> Si true, objet[methodName] est traitée comme un setter. Cette option ne peut pas être utilisée avec l'option getter. Par défaut : false.
    • times <integer> Le nombre de fois où la simulation utilisera le comportement de implémentation. Une fois que la méthode simulée a été appelée times fois, elle restaure automatiquement le comportement d'origine. Cette valeur doit être un entier supérieur à zéro. Par défaut : Infinity.
  • Retourne : <Proxy> La méthode simulée. La méthode simulée contient une propriété mock spéciale, qui est une instance de MockFunctionContext, et peut être utilisée pour inspecter et modifier le comportement de la méthode simulée.

Cette fonction est utilisée pour créer une simulation sur une méthode d'objet existante. L'exemple suivant montre comment une simulation est créée sur une méthode d'objet existante.

js
test('espionne une méthode d’objet', t => {
  const nombre = {
    value: 5,
    soustraire(a) {
      return this.value - a
    },
  }

  t.mock.method(nombre, 'soustraire')
  assert.strictEqual(nombre.soustraire.mock.callCount(), 0)
  assert.strictEqual(nombre.soustraire(3), 2)
  assert.strictEqual(nombre.soustraire.mock.callCount(), 1)

  const appel = nombre.soustraire.mock.calls[0]

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

mock.module(specifier[, options])

Ajouté dans : v22.3.0, v20.18.0

[Stable: 1 - Expérimental]

Stable: 1 Stabilité: 1.0 - Développement précoce

  • specifier <string> | <URL> Une chaîne de caractères identifiant le module à simuler.

  • options <Object> Options de configuration facultatives pour le module simulé. Les propriétés suivantes sont prises en charge :

    • cache <boolean> Si la valeur est false, chaque appel à require() ou import() génère un nouveau module simulé. Si la valeur est true, les appels suivants renvoient le même module simulé, et le module simulé est inséré dans le cache CommonJS. Par défaut : false.
    • defaultExport <any> Une valeur facultative utilisée comme exportation par défaut du module simulé. Si cette valeur n’est pas fournie, les simulations ESM n’incluent pas d’exportation par défaut. Si la simulation est un module CommonJS ou intégré, ce paramètre est utilisé comme valeur de module.exports. Si cette valeur n’est pas fournie, les simulations CJS et intégrées utilisent un objet vide comme valeur de module.exports.
    • namedExports <Object> Un objet facultatif dont les clés et les valeurs sont utilisées pour créer les exportations nommées du module simulé. Si la simulation est un module CommonJS ou intégré, ces valeurs sont copiées dans module.exports. Par conséquent, si une simulation est créée avec à la fois des exportations nommées et une exportation par défaut non-objet, la simulation lèvera une exception lorsqu’elle sera utilisée comme module CJS ou intégré.
  • Retourne : <MockModuleContext> Un objet qui peut être utilisé pour manipuler la simulation.

Cette fonction est utilisée pour simuler les exportations des modules ECMAScript, des modules CommonJS et des modules intégrés de Node.js. Toute référence au module original antérieure à la simulation n’est pas impactée. Afin d’activer la simulation de modules, Node.js doit être démarré avec l’indicateur de ligne de commande --experimental-test-module-mocks.

L’exemple suivant montre comment une simulation est créée pour un module.

js
test('simule un module intégré dans les deux systèmes de modules', async t => {
  // Créez une simulation de 'node:readline' avec une exportation nommée 'fn', qui
  // n'existe pas dans le module 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() est une exportation du module 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 simulation est restaurée, donc le module intégré original est retourné.
  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()

Ajouté dans : v19.1.0, v18.13.0

Cette fonction restaure le comportement par défaut de toutes les simulations qui ont été précédemment créées par ce MockTracker et dissocie les simulations de l'instance MockTracker. Une fois dissociées, les simulations peuvent toujours être utilisées, mais l'instance MockTracker ne peut plus être utilisée pour réinitialiser leur comportement ou interagir avec elles de quelque manière que ce soit.

Après chaque test, cette fonction est appelée sur le MockTracker du contexte de test. Si le MockTracker global est utilisé de manière intensive, il est recommandé d'appeler cette fonction manuellement.

mock.restoreAll()

Ajouté dans : v19.1.0, v18.13.0

Cette fonction restaure le comportement par défaut de toutes les simulations qui ont été précédemment créées par ce MockTracker. Contrairement à mock.reset(), mock.restoreAll() ne dissocie pas les simulations de l'instance MockTracker.

mock.setter(objet, nomDeMethode[, implémentation][, options])

Ajouté dans : v19.3.0, v18.13.0

Cette fonction est un sucre syntaxique pour MockTracker.method avec options.setter défini sur true.

Classe : MockTimers

[Historique]

VersionModifications
v23.1.0Les simulations de temporisateurs sont désormais stables.
v20.4.0, v18.19.0Ajouté dans : v20.4.0, v18.19.0

[Stable : 2 - Stable]

Stable : 2 Stabilité : 2 - Stable

La simulation de temporisateurs est une technique couramment utilisée dans les tests logiciels pour simuler et contrôler le comportement des temporisateurs, tels que setInterval et setTimeout, sans attendre réellement les intervalles de temps spécifiés.

MockTimers est également capable de simuler l'objet Date.

Le MockTracker fournit une exportation timers de niveau supérieur qui est une instance MockTimers.

timers.enable([enableOptions])

[Historique]

VersionModifications
v21.2.0, v20.11.0Paramètres mis à jour pour être un objet d'option avec les API disponibles et l'époque initiale par défaut.
v20.4.0, v18.19.0Ajouté dans : v20.4.0, v18.19.0

Active la simulation de temporisateurs pour les temporisateurs spécifiés.

  • enableOptions <Object> Options de configuration facultatives pour l'activation de la simulation de temporisateurs. Les propriétés suivantes sont prises en charge :
    • apis <Array> Un tableau facultatif contenant les temporisateurs à simuler. Les valeurs de temporisateur actuellement prises en charge sont 'setInterval', 'setTimeout', 'setImmediate' et 'Date'. Par défaut : ['setInterval', 'setTimeout', 'setImmediate', 'Date']. Si aucun tableau n'est fourni, toutes les API liées au temps ('setInterval', 'clearInterval', 'setTimeout', 'clearTimeout', 'setImmediate' et 'clearImmediate') seront simulées par défaut.
    • now <number> | <Date> Un nombre ou un objet Date facultatif représentant l'heure initiale (en millisecondes) à utiliser comme valeur pour Date.now(). Par défaut : 0.

Remarque : Lorsque vous activez la simulation pour un temporisateur spécifique, sa fonction de suppression associée sera également simulée implicitement.

Remarque : La simulation de Date affectera le comportement des temporisateurs simulés car ils utilisent la même horloge interne.

Exemple d'utilisation sans définition de l'heure initiale :

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

L'exemple ci-dessus active la simulation pour le temporisateur setInterval et simule implicitement la fonction clearInterval. Seules les fonctions setInterval et clearInterval de node:timers, node:timers/promises et globalThis seront simulées.

Exemple d'utilisation avec l'heure initiale définie

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 })

Exemple d'utilisation avec un objet Date initial comme heure définie

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() })

Alternativement, si vous appelez mock.timers.enable() sans aucun paramètre :

Tous les temporisateurs ('setInterval', 'clearInterval', 'setTimeout', 'clearTimeout', 'setImmediate' et 'clearImmediate') seront simulés. Les fonctions setInterval, clearInterval, setTimeout, clearTimeout, setImmediate et clearImmediate de node:timers, node:timers/promises et globalThis seront simulées. Ainsi que l'objet Date global.

timers.reset()

Ajouté dans : v20.4.0, v18.19.0

Cette fonction restaure le comportement par défaut de toutes les simulations qui ont été précédemment créées par cette instance MockTimers et dissocie les simulations de l’instance MockTracker.

Remarque : Une fois chaque test terminé, cette fonction est appelée sur le MockTracker du contexte de test.

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

timers[Symbol.dispose]()

Appelle timers.reset().

timers.tick([millisecondes])

Ajouté dans : v20.4.0, v18.19.0

Avance le temps pour tous les temporisateurs simulés.

  • millisecondes <number> La quantité de temps, en millisecondes, pour faire avancer les temporisateurs. Par défaut : 1.

Remarque : Cela diffère de la manière dont setTimeout se comporte dans Node.js et n’accepte que les nombres positifs. Dans Node.js, setTimeout avec des nombres négatifs n’est pris en charge que pour des raisons de compatibilité web.

L’exemple suivant simule une fonction setTimeout et, en utilisant .tick, avance dans le temps en déclenchant tous les temporisateurs en attente.

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

test('simule setTimeout pour qu’il soit exécuté de manière synchrone sans avoir à l’attendre réellement', context => {
  const fn = context.mock.fn()

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

  setTimeout(fn, 9999)

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

  // Avancer dans le temps
  context.mock.timers.tick(9999)

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

test('simule setTimeout pour qu’il soit exécuté de manière synchrone sans avoir à l’attendre réellement', context => {
  const fn = context.mock.fn()
  context.mock.timers.enable({ apis: ['setTimeout'] })

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

  // Avancer dans le temps
  context.mock.timers.tick(9999)

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

Alternativement, la fonction .tick peut être appelée plusieurs fois

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

test('simule setTimeout pour qu’il soit exécuté de manière synchrone sans avoir à l’attendre réellement', 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('simule setTimeout pour qu’il soit exécuté de manière synchrone sans avoir à l’attendre réellement', 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)
})

L’avance du temps à l’aide de .tick avancera également le temps pour tout objet Date créé après l’activation de la simulation (si Date était également configuré pour être simulé).

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

test('simule setTimeout pour qu’il soit exécuté de manière synchrone sans avoir à l’attendre réellement', 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)

  // Avancer dans le temps
  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('simule setTimeout pour qu’il soit exécuté de manière synchrone sans avoir à l’attendre réellement', 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)

  // Avancer dans le temps
  context.mock.timers.tick(9999)
  assert.strictEqual(fn.mock.callCount(), 1)
  assert.strictEqual(Date.now(), 9999)
})

Utilisation de fonctions clear

Comme mentionné, toutes les fonctions clear des minuteurs (clearTimeout, clearInterval et clearImmediate) sont implicitement simulées. Jetez un œil à cet exemple utilisant setTimeout :

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

test('simule setTimeout pour qu’il soit exécuté de manière synchrone sans avoir à l’attendre', context => {
  const fn = context.mock.fn()

  // Choisissez éventuellement ce qu’il faut simuler
  context.mock.timers.enable({ apis: ['setTimeout'] })
  const id = setTimeout(fn, 9999)

  // Simulé implicitement également
  clearTimeout(id)
  context.mock.timers.tick(9999)

  // Comme ce setTimeout a été effacé, la fonction simulée ne sera jamais appelée
  assert.strictEqual(fn.mock.callCount(), 0)
})
js
const assert = require('node:assert')
const { test } = require('node:test')

test('simule setTimeout pour qu’il soit exécuté de manière synchrone sans avoir à l’attendre', context => {
  const fn = context.mock.fn()

  // Choisissez éventuellement ce qu’il faut simuler
  context.mock.timers.enable({ apis: ['setTimeout'] })
  const id = setTimeout(fn, 9999)

  // Simulé implicitement également
  clearTimeout(id)
  context.mock.timers.tick(9999)

  // Comme ce setTimeout a été effacé, la fonction simulée ne sera jamais appelée
  assert.strictEqual(fn.mock.callCount(), 0)
})

Utilisation des modules de minuteurs Node.js

Une fois que vous avez activé la simulation de minuteurs, les modules node:timers, node:timers/promises et les minuteurs du contexte global de Node.js sont activés :

Remarque : La déstructuration de fonctions telles que import { setTimeout } from 'node:timers' n’est actuellement pas prise en charge par cette API.

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

test('simule setTimeout pour qu’il soit exécuté de manière synchrone sans avoir à l’attendre', async context => {
  const globalTimeoutObjectSpy = context.mock.fn()
  const nodeTimerSpy = context.mock.fn()
  const nodeTimerPromiseSpy = context.mock.fn()

  // Choisissez éventuellement ce qu’il faut simuler
  context.mock.timers.enable({ apis: ['setTimeout'] })
  setTimeout(globalTimeoutObjectSpy, 9999)
  nodeTimers.setTimeout(nodeTimerSpy, 9999)

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

  // Avancer dans le temps
  context.mock.timers.tick(9999)
  assert.strictEqual(globalTimeoutObjectSpy.mock.callCount(), 1)
  assert.strictEqual(nodeTimerSpy.mock.callCount(), 1)
  await promise
  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('simule setTimeout pour qu’il soit exécuté de manière synchrone sans avoir à l’attendre', async context => {
  const globalTimeoutObjectSpy = context.mock.fn()
  const nodeTimerSpy = context.mock.fn()
  const nodeTimerPromiseSpy = context.mock.fn()

  // Choisissez éventuellement ce qu’il faut simuler
  context.mock.timers.enable({ apis: ['setTimeout'] })
  setTimeout(globalTimeoutObjectSpy, 9999)
  nodeTimers.setTimeout(nodeTimerSpy, 9999)

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

  // Avancer dans le temps
  context.mock.timers.tick(9999)
  assert.strictEqual(globalTimeoutObjectSpy.mock.callCount(), 1)
  assert.strictEqual(nodeTimerSpy.mock.callCount(), 1)
  await promise
  assert.strictEqual(nodeTimerPromiseSpy.mock.callCount(), 1)
})

Dans Node.js, setInterval de node:timers/promises est un AsyncGenerator et est également pris en charge par cette API :

js
import assert from 'node:assert'
import { test } from 'node:test'
import nodeTimersPromises from 'node:timers/promises'
test('doit effectuer un tick cinq fois en testant un cas d’utilisation réel', 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('doit effectuer un tick cinq fois en testant un cas d’utilisation réel', 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()

Ajouté dans : v20.4.0, v18.19.0

Déclenche immédiatement tous les minuteurs simulés en attente. Si l'objet Date est également simulé, il avancera également l'objet Date jusqu'à l'heure du minuteur le plus éloigné.

L'exemple ci-dessous déclenche immédiatement tous les minuteurs en attente, ce qui les fait s'exécuter sans aucun délai.

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

test('runAll fonctionne selon l’ordre donné', contexte => {
  contexte.mock.timers.enable({ apis: ['setTimeout', 'Date'] })
  const results = []
  setTimeout(() => results.push(1), 9999)

  // Notez que si les deux minuteurs ont le même délai d’attente,
  // l’ordre d’exécution est garanti
  setTimeout(() => results.push(3), 8888)
  setTimeout(() => results.push(2), 8888)

  assert.deepStrictEqual(results, [])

  contexte.mock.timers.runAll()
  assert.deepStrictEqual(results, [3, 2, 1])
  // L’objet Date est également avancé jusqu’à l’heure du minuteur le plus éloigné
  assert.strictEqual(Date.now(), 9999)
})
js
const assert = require('node:assert')
const { test } = require('node:test')

test('runAll fonctionne selon l’ordre donné', contexte => {
  contexte.mock.timers.enable({ apis: ['setTimeout', 'Date'] })
  const results = []
  setTimeout(() => results.push(1), 9999)

  // Notez que si les deux minuteurs ont le même délai d’attente,
  // l’ordre d’exécution est garanti
  setTimeout(() => results.push(3), 8888)
  setTimeout(() => results.push(2), 8888)

  assert.deepStrictEqual(results, [])

  contexte.mock.timers.runAll()
  assert.deepStrictEqual(results, [3, 2, 1])
  // L’objet Date est également avancé jusqu’à l’heure du minuteur le plus éloigné
  assert.strictEqual(Date.now(), 9999)
})

Remarque : La fonction runAll() est spécialement conçue pour déclencher des minuteurs dans le cadre de la simulation de minuteurs. Elle n’a aucun effet sur les horloges système en temps réel ou les minuteurs réels en dehors de l’environnement de simulation.

timers.setTime(milliseconds)

Ajouté dans : v21.2.0, v20.11.0

Définit l’horodatage Unix actuel qui sera utilisé comme référence pour tous les objets Date simulés.

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

test('runAll fonctionne selon l’ordre donné', contexte => {
  const now = Date.now()
  const setTime = 1000
  // Date.now n’est pas simulé
  assert.deepStrictEqual(Date.now(), now)

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

test('setTime remplace l’heure actuelle', contexte => {
  const now = Date.now()
  const setTime = 1000
  // Date.now n’est pas simulé
  assert.deepStrictEqual(Date.now(), now)

  contexte.mock.timers.enable({ apis: ['Date'] })
  contexte.mock.timers.setTime(setTime)
  // Date.now est maintenant 1000
  assert.strictEqual(Date.now(), setTime)
})

Dates et minuteurs fonctionnant ensemble

Les dates et les objets minuteurs sont dépendants les uns des autres. Si vous utilisez setTime() pour passer l'heure actuelle à l'objet Date simulé, les minuteurs définis avec setTimeout et setInterval ne seront pas affectés.

Cependant, la méthode tick fera avancer l'objet Date simulé.

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

test('exécute toutes les fonctions dans l’ordre donné', 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 date est avancée, mais les minuteurs ne sont pas incrémentés
  assert.strictEqual(Date.now(), 12000)
})
js
const assert = require('node:assert')
const { test } = require('node:test')

test('exécute toutes les fonctions dans l’ordre donné', 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 date est avancée, mais les minuteurs ne sont pas incrémentés
  assert.strictEqual(Date.now(), 12000)
})

Classe : TestsStream

[Historique]

VersionModifications
v20.0.0, v19.9.0, v18.17.0a ajouté le type aux événements test:pass et test:fail lorsque le test est une suite.
v18.9.0, v16.19.0Ajouté dans : v18.9.0, v16.19.0

Un appel réussi à la méthode run() renverra un nouvel objet <TestsStream>, qui transmettra une série d’événements représentant l’exécution des tests. TestsStream émettra des événements, dans l’ordre de la définition des tests.

Certains des événements sont garantis d’être émis dans le même ordre que les tests sont définis, tandis que d’autres sont émis dans l’ordre dans lequel les tests sont exécutés.

Événement : 'test:coverage'

  • data <Object>

    • summary <Object> Un objet contenant le rapport de couverture.

    • files <Array> Un tableau de rapports de couverture pour chaque fichier. Chaque rapport est un objet ayant le schéma suivant :

    • path <string> Le chemin absolu du fichier.

    • totalLineCount <number> Le nombre total de lignes.

    • totalBranchCount <number> Le nombre total de branches.

    • totalFunctionCount <number> Le nombre total de fonctions.

    • coveredLineCount <number> Le nombre de lignes couvertes.

    • coveredBranchCount <number> Le nombre de branches couvertes.

    • coveredFunctionCount <number> Le nombre de fonctions couvertes.

    • coveredLinePercent <number> Le pourcentage de lignes couvertes.

    • coveredBranchPercent <number> Le pourcentage de branches couvertes.

    • coveredFunctionPercent <number> Le pourcentage de fonctions couvertes.

    • functions <Array> Un tableau de fonctions représentant la couverture des fonctions.

    • name <string> Le nom de la fonction.

    • line <number> Le numéro de ligne où la fonction est définie.

    • count <number> Le nombre de fois où la fonction a été appelée.

    • branches <Array> Un tableau de branches représentant la couverture des branches.

    • line <number> Le numéro de ligne où la branche est définie.

    • count <number> Le nombre de fois où la branche a été empruntée.

    • lines <Array> Un tableau de lignes représentant les numéros de ligne et le nombre de fois où elles ont été couvertes.

    • line <number> Le numéro de ligne.

    • count <number> Le nombre de fois où la ligne a été couverte.

    • thresholds <Object> Un objet indiquant si la couverture de chaque type de couverture est atteinte ou non.

    • function <number> Le seuil de couverture des fonctions.

    • branch <number> Le seuil de couverture des branches.

    • line <number> Le seuil de couverture des lignes.

    • totals <Object> Un objet contenant un résumé de la couverture pour tous les fichiers.

    • totalLineCount <number> Le nombre total de lignes.

    • totalBranchCount <number> Le nombre total de branches.

    • totalFunctionCount <number> Le nombre total de fonctions.

    • coveredLineCount <number> Le nombre de lignes couvertes.

    • coveredBranchCount <number> Le nombre de branches couvertes.

    • coveredFunctionCount <number> Le nombre de fonctions couvertes.

    • coveredLinePercent <number> Le pourcentage de lignes couvertes.

    • coveredBranchPercent <number> Le pourcentage de branches couvertes.

    • coveredFunctionPercent <number> Le pourcentage de fonctions couvertes.

    • workingDirectory <string> Le répertoire de travail lorsque la couverture de code a commencé. Ceci est utile pour afficher les noms de chemins relatifs au cas où les tests ont modifié le répertoire de travail du processus Node.js.

    • nesting <number> Le niveau d'imbrication du test.

Émis lorsque la couverture de code est activée et que tous les tests sont terminés.

Événement : 'test:complete'

Émis lorsqu’un test termine son exécution. Cet événement n’est pas émis dans le même ordre que les tests sont définis. Les événements déclaratifs correspondants dans l’ordre sont 'test:pass' et 'test:fail'.

Événement : 'test:dequeue'

  • data <Object>
    • column <number> | <undefined> Le numéro de colonne où le test est défini, ou undefined si le test a été exécuté via le REPL.
    • file <string> | <undefined> Le chemin du fichier de test, undefined si le test a été exécuté via le REPL.
    • line <number> | <undefined> Le numéro de ligne où le test est défini, ou undefined si le test a été exécuté via le REPL.
    • name <string> Le nom du test.
    • nesting <number> Le niveau d’imbrication du test.

Émis lorsqu’un test est retiré de la file d’attente, juste avant son exécution. Il n’est pas garanti que cet événement soit émis dans le même ordre que la définition des tests. L’événement ordonné de déclaration correspondant est 'test:start'.

Événement : 'test:diagnostic'

  • data <Object>
    • column <number> | <undefined> Le numéro de colonne où le test est défini, ou undefined si le test a été exécuté via le REPL.
    • file <string> | <undefined> Le chemin du fichier de test, undefined si le test a été exécuté via le REPL.
    • line <number> | <undefined> Le numéro de ligne où le test est défini, ou undefined si le test a été exécuté via le REPL.
    • message <string> Le message de diagnostic.
    • nesting <number> Le niveau d’imbrication du test.

Émis lorsque context.diagnostic est appelé. Il est garanti que cet événement soit émis dans le même ordre que la définition des tests.

Événement : 'test:enqueue'

  • data <Object>
    • column <number> | <undefined> Numéro de la colonne où le test est défini, ou undefined si le test a été exécuté via le REPL.
    • file <string> | <undefined> Chemin du fichier de test, undefined si le test a été exécuté via le REPL.
    • line <number> | <undefined> Numéro de la ligne où le test est défini, ou undefined si le test a été exécuté via le REPL.
    • name <string> Nom du test.
    • nesting <number> Niveau d’imbrication du test.

Émis lorsqu’un test est mis en file d’attente pour exécution.

Événement : 'test:fail'

Émis lorsqu’un test échoue. Cet événement est garanti d’être émis dans le même ordre que celui dans lequel les tests sont définis. L’événement correspondant d’exécution ordonnée est 'test:complete'.

Événement : 'test:pass'

Émis lorsqu'un test réussit. Cet événement est garanti d'être émis dans le même ordre que les tests sont définis. L'événement d'exécution ordonnée correspondant est 'test:complete'.

Événement : 'test:plan'

  • data <Object>
    • column <number> | <undefined> Le numéro de colonne où le test est défini, ou undefined si le test a été exécuté via le REPL.
    • file <string> | <undefined> Le chemin du fichier de test, undefined si le test a été exécuté via le REPL.
    • line <number> | <undefined> Le numéro de ligne où le test est défini, ou undefined si le test a été exécuté via le REPL.
    • nesting <number> Le niveau d’imbrication du test.
    • count <number> Le nombre de sous-tests qui ont été exécutés.

Émis lorsque tous les sous-tests d’un test donné sont terminés. Il est garanti que cet événement est émis dans le même ordre que celui dans lequel les tests sont définis.

Événement : 'test:start'

  • data <Object>
    • column <number> | <undefined> Le numéro de colonne où le test est défini, ou undefined si le test a été exécuté via le REPL.
    • file <string> | <undefined> Le chemin du fichier de test, undefined si le test a été exécuté via le REPL.
    • line <number> | <undefined> Le numéro de ligne où le test est défini, ou undefined si le test a été exécuté via le REPL.
    • name <string> Le nom du test.
    • nesting <number> Le niveau d’imbrication du test.

Émis lorsqu’un test commence à signaler son propre statut et celui de ses sous-tests. Il est garanti que cet événement est émis dans le même ordre que celui dans lequel les tests sont définis. L’événement ordonné d’exécution correspondant est 'test:dequeue'.

Événement : 'test:stderr'

Émis lorsqu'un test en cours d'exécution écrit dans stderr. Cet événement n'est émis que si l'indicateur --test est passé. Il n'est pas garanti que cet événement soit émis dans le même ordre que celui dans lequel les tests sont définis.

Événement : 'test:stdout'

Émis lorsqu'un test en cours d'exécution écrit dans stdout. Cet événement n'est émis que si l'indicateur --test est passé. Il n'est pas garanti que cet événement soit émis dans le même ordre que celui dans lequel les tests sont définis.

Événement : 'test:summary'

  • data <Object>

    • counts <Object> Un objet contenant les comptes des différents résultats de test.

    • cancelled <number> Le nombre total de tests annulés.

    • failed <number> Le nombre total de tests ayant échoué.

    • passed <number> Le nombre total de tests réussis.

    • skipped <number> Le nombre total de tests ignorés.

    • suites <number> Le nombre total de suites exécutées.

    • tests <number> Le nombre total de tests exécutés, à l'exclusion des suites.

    • todo <number> Le nombre total de tests TODO.

    • topLevel <number> Le nombre total de tests et de suites de niveau supérieur.

    • duration_ms <number> La durée de l'exécution du test en millisecondes.

    • file <string> | <undefined> Le chemin du fichier de test qui a généré le résumé. Si le résumé correspond à plusieurs fichiers, cette valeur est undefined.

    • success <boolean> Indique si l'exécution du test est considérée comme réussie ou non. Si une condition d'erreur se produit, comme un test échouant ou un seuil de couverture non atteint, cette valeur sera définie sur false.

Émis lorsqu'une exécution de test est terminée. Cet événement contient des métriques relatives à l'exécution de test terminée et est utile pour déterminer si une exécution de test a réussi ou échoué. Si l'isolation des tests au niveau du processus est utilisée, un événement 'test:summary' est généré pour chaque fichier de test, en plus d'un résumé cumulatif final.

Événement : 'test:watch:drained'

Émis lorsqu’il n’y a plus de tests en file d’attente pour l’exécution en mode surveillance.

Classe : TestContext

[Historique]

VersionModifications
v20.1.0, v18.17.0La fonction before a été ajoutée à TestContext.
v18.0.0, v16.17.0Ajouté dans : v18.0.0, v16.17.0

Une instance de TestContext est passée à chaque fonction de test afin d’interagir avec l’exécuteur de test. Cependant, le constructeur TestContext n’est pas exposé dans le cadre de l’API.

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

Ajouté dans : v20.1.0, v18.17.0

  • fn <Function> | <AsyncFunction> La fonction de hook. Le premier argument de cette fonction est un objet TestContext. Si le hook utilise des rappels, la fonction de rappel est passée comme deuxième argument. Par défaut : Une fonction no-op.
  • options <Object> Options de configuration du hook. Les propriétés suivantes sont prises en charge :
    • signal <AbortSignal> Permet d’abandonner un hook en cours.
    • timeout <number> Un nombre de millisecondes après lequel le hook échouera. S’il n’est pas spécifié, les sous-tests héritent de cette valeur de leur parent. Par défaut : Infinity.

Cette fonction est utilisée pour créer un hook qui s’exécute avant le sous-test du test actuel.

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

Ajouté dans : v18.8.0, v16.18.0

  • fn <Function> | <AsyncFunction> La fonction de hook. Le premier argument de cette fonction est un objet TestContext. Si le hook utilise des rappels, la fonction de rappel est passée comme deuxième argument. Par défaut : Une fonction no-op.
  • options <Object> Options de configuration du hook. Les propriétés suivantes sont prises en charge :
    • signal <AbortSignal> Permet d’abandonner un hook en cours.
    • timeout <number> Un nombre de millisecondes après lequel le hook échouera. S’il n’est pas spécifié, les sous-tests héritent de cette valeur de leur parent. Par défaut : Infinity.

Cette fonction est utilisée pour créer un hook qui s’exécute avant chaque sous-test du test actuel.

js
test('test de niveau supérieur', async t => {
  t.beforeEach(t => t.diagnostic(`sur le point d’exécuter ${t.name}`))
  await t.test('Ceci est un sous-test', t => {
    assert.ok('une assertion pertinente ici')
  })
})

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

Ajouté dans : v19.3.0, v18.13.0

  • fn <Function> | <AsyncFunction> La fonction de crochet. Le premier argument de cette fonction est un objet TestContext. Si le crochet utilise des rappels, la fonction de rappel est passée comme deuxième argument. Par défaut : une fonction sans opération.
  • options <Object> Options de configuration du crochet. Les propriétés suivantes sont prises en charge :
    • signal <AbortSignal> Permet d’annuler un crochet en cours.
    • timeout <number> Nombre de millisecondes après lesquelles le crochet échouera. S’il n’est pas spécifié, les sous-tests héritent de cette valeur de leur parent. Par défaut : Infinity.

Cette fonction est utilisée pour créer un crochet qui s’exécute une fois le test actuel terminé.

js
test('test de niveau supérieur', async t => {
  t.after(t => t.diagnostic(`exécution terminée de ${t.name}`))
  assert.ok('une assertion pertinente ici')
})

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

Ajouté dans : v18.8.0, v16.18.0

  • fn <Function> | <AsyncFunction> La fonction de crochet. Le premier argument de cette fonction est un objet TestContext. Si le crochet utilise des rappels, la fonction de rappel est passée comme deuxième argument. Par défaut : une fonction sans opération.
  • options <Object> Options de configuration du crochet. Les propriétés suivantes sont prises en charge :
    • signal <AbortSignal> Permet d’annuler un crochet en cours.
    • timeout <number> Nombre de millisecondes après lesquelles le crochet échouera. S’il n’est pas spécifié, les sous-tests héritent de cette valeur de leur parent. Par défaut : Infinity.

Cette fonction est utilisée pour créer un crochet qui s’exécute après chaque sous-test du test actuel.

js
test('test de niveau supérieur', async t => {
  t.afterEach(t => t.diagnostic(`exécution terminée de ${t.name}`))
  await t.test('Ceci est un sous-test', t => {
    assert.ok('une assertion pertinente ici')
  })
})

context.assert

Ajouté dans : v22.2.0, v20.15.0

Un objet contenant des méthodes d'assertion liées à context. Les fonctions de premier niveau du module node:assert sont exposées ici dans le but de créer des plans de test.

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

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

Ajouté dans : v22.3.0

[Stable: 1 - Expérimental]

Stable: 1 Stabilité : 1.0 - Développement initial

  • value <any> Une valeur à sérialiser en chaîne de caractères. Si Node.js a été démarré avec l'indicateur --test-update-snapshots, la valeur sérialisée est écrite dans le fichier d'instantané. Sinon, la valeur sérialisée est comparée à la valeur correspondante dans le fichier d'instantané existant.
  • options <Object> Options de configuration facultatives. Les propriétés suivantes sont prises en charge :
    • serializers <Array> Un tableau de fonctions synchrones utilisées pour sérialiser value en une chaîne de caractères. value est transmis comme seul argument à la première fonction de sérialisation. La valeur de retour de chaque sérialiseur est transmise comme entrée au sérialiseur suivant. Une fois que tous les sérialiseurs ont été exécutés, la valeur résultante est convertie en chaîne de caractères. Par défaut : Si aucun sérialiseur n'est fourni, les sérialiseurs par défaut du lanceur de test sont utilisés.

Cette fonction implémente des assertions pour les tests d'instantanés.

js
test('test d'instantané avec sérialisation par défaut', (t) => {
  t.assert.snapshot({ value1: 1, value2: 2 });
});

test('test d'instantané avec sérialisation personnalisée', (t) => {
  t.assert.snapshot({ value3: 3, value4: 4 }, {
    serializers: [(value) => JSON.stringify(value)],
  });
});

context.diagnostic(message)

Ajouté dans : v18.0.0, v16.17.0

Cette fonction est utilisée pour écrire des diagnostics dans la sortie. Toute information de diagnostic est incluse à la fin des résultats du test. Cette fonction ne renvoie pas de valeur.

js
test('test de niveau supérieur', t => {
  t.diagnostic('Un message de diagnostic')
})

context.filePath

Ajouté dans : v22.6.0, v20.16.0

Le chemin absolu du fichier de test qui a créé le test actuel. Si un fichier de test importe des modules supplémentaires qui génèrent des tests, les tests importés renverront le chemin du fichier de test racine.

context.fullName

Ajouté dans : v22.3.0

Le nom du test et de chacun de ses ancêtres, séparés par \>.

context.name

Ajouté dans : v18.8.0, v16.18.0

Le nom du test.

context.plan(count)

[Historique]

VersionChangements
v23.4.0Cette fonction n’est plus expérimentale.
v22.2.0, v20.15.0Ajouté dans : v22.2.0, v20.15.0
  • count <number> Le nombre d’assertions et de sous-tests qui doivent être exécutés.

Cette fonction est utilisée pour définir le nombre d’assertions et de sous-tests qui doivent être exécutés dans le test. Si le nombre d’assertions et de sous-tests qui s’exécutent ne correspond pas au nombre prévu, le test échouera.

js
test('test de niveau supérieur', t => {
  t.plan(2)
  t.assert.ok('une assertion pertinente ici')
  t.test('sous-test', () => {})
})

Lorsque vous travaillez avec du code asynchrone, la fonction plan peut être utilisée pour vous assurer que le nombre correct d’assertions est exécuté :

js
test('planification avec des flux', (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)

Ajouté dans : v18.0.0, v16.17.0

  • shouldRunOnlyTests <boolean> Indique s’il faut exécuter les tests only ou non.

Si shouldRunOnlyTests est truthy, le contexte du test n’exécutera que les tests dont l’option only est définie. Sinon, tous les tests sont exécutés. Si Node.js n’a pas été démarré avec l’option de ligne de commande --test-only, cette fonction est une opération sans effet.

js
test('top level test', t => {
  // Le contexte du test peut être configuré pour exécuter les sous-tests avec l’option 'only'.
  t.runOnly(true)
  return Promise.all([t.test('this subtest is now skipped'), t.test('this subtest is run', { only: true })])
})

context.signal

Ajouté dans : v18.7.0, v16.17.0

Peut être utilisé pour interrompre les sous-tâches de test lorsque le test a été interrompu.

js
test('top level test', async t => {
  await fetch('some/uri', { signal: t.signal })
})

context.skip([message])

Ajouté dans : v18.0.0, v16.17.0

  • message <string> Message de saut optionnel.

Cette fonction fait que la sortie du test indique que le test est ignoré. Si message est fourni, il est inclus dans la sortie. L’appel de skip() ne met pas fin à l’exécution de la fonction de test. Cette fonction ne renvoie pas de valeur.

js
test('top level test', t => {
  // Assurez-vous de revenir ici aussi si le test contient une logique supplémentaire.
  t.skip('this is skipped')
})

context.todo([message])

Ajouté dans : v18.0.0, v16.17.0

  • message <string> Message TODO optionnel.

Cette fonction ajoute une directive TODO à la sortie du test. Si message est fourni, il est inclus dans la sortie. L’appel de todo() ne met pas fin à l’exécution de la fonction de test. Cette fonction ne renvoie pas de valeur.

js
test('top level test', t => {
  // Ce test est marqué comme `TODO`
  t.todo('this is a todo')
})

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

[Historique]

VersionModifications
v18.8.0, v16.18.0Ajout d'une option signal.
v18.7.0, v16.17.0Ajout d'une option timeout.
v18.0.0, v16.17.0Ajouté dans : v18.0.0, v16.17.0
  • name <string> Le nom du sous-test, qui est affiché lors de la communication des résultats du test. Par défaut: la propriété name de fn, ou '\<anonymous\>' si fn n'a pas de nom.

  • options <Object> Options de configuration pour le sous-test. Les propriétés suivantes sont prises en charge :

    • concurrency <number> | <boolean> | <null> Si un nombre est fourni, ce nombre de tests s'exécutera en parallèle au sein du thread d'application. Si true, tous les sous-tests s'exécuteront en parallèle. Si false, un seul test à la fois sera exécuté. Si non spécifié, les sous-tests héritent de cette valeur de leur parent. Par défaut : null.
    • only <boolean> Si la valeur est « truthy » et que le contexte de test est configuré pour exécuter uniquement les tests only, ce test sera exécuté. Sinon, le test est ignoré. Par défaut : false.
    • signal <AbortSignal> Permet d'abandonner un test en cours.
    • skip <boolean> | <string> Si la valeur est « truthy », le test est ignoré. Si une chaîne est fournie, cette chaîne est affichée dans les résultats du test comme motif de l'ignorance du test. Par défaut : false.
    • todo <boolean> | <string> Si la valeur est « truthy », le test est marqué comme TODO. Si une chaîne est fournie, cette chaîne est affichée dans les résultats du test comme motif pour lequel le test est TODO. Par défaut : false.
    • timeout <number> Nombre de millisecondes après lequel le test échouera. Si non spécifié, les sous-tests héritent de cette valeur de leur parent. Par défaut : Infinity.
    • plan <number> Le nombre d'assertions et de sous-tests prévus pour être exécutés dans le test. Si le nombre d'assertions exécutées dans le test ne correspond pas au nombre spécifié dans le plan, le test échouera. Par défaut : undefined.
  • fn <Function> | <AsyncFunction> La fonction testée. Le premier argument de cette fonction est un objet TestContext. Si le test utilise des rappels, la fonction de rappel est transmise comme deuxième argument. Par défaut : une fonction no-op.

  • Retourne : <Promise> Résolue avec undefined une fois le test terminé.

Cette fonction est utilisée pour créer des sous-tests dans le test actuel. Cette fonction se comporte de la même manière que la fonction de niveau supérieur test().

js
test('test de niveau supérieur', async t => {
  await t.test('Ceci est un sous-test', { only: false, skip: false, concurrency: 1, todo: false, plan: 1 }, t => {
    t.assert.ok('une assertion pertinente ici')
  })
})

Classe : SuiteContext

Ajouté dans : v18.7.0, v16.17.0

Une instance de SuiteContext est transmise à chaque fonction de suite afin d’interagir avec l’exécuteur de tests. Cependant, le constructeur SuiteContext n’est pas exposé dans le cadre de l’API.

context.filePath

Ajouté dans : v22.6.0

Le chemin absolu du fichier de test qui a créé la suite actuelle. Si un fichier de test importe des modules supplémentaires qui génèrent des suites, les suites importées renverront le chemin du fichier de test racine.

context.name

Ajouté dans : v18.8.0, v16.18.0

Le nom de la suite.

context.signal

Ajouté dans : v18.7.0, v16.17.0

Peut être utilisé pour annuler les sous-tâches de test lorsque le test a été annulé.