テストランナー
[履歴]
バージョン | 変更 |
---|---|
v20.0.0 | テストランナーは安定版になりました。 |
v18.0.0, v16.17.0 | 追加: v18.0.0, v16.17.0 |
ソースコード: lib/test.js
node:test
モジュールは、JavaScript テストの作成を容易にします。アクセスするには:
import test from 'node:test'
const test = require('node:test')
このモジュールは、node:
スキームでのみ使用できます。
test
モジュールで作成されたテストは、単一の関数で構成され、3 つの方法のいずれかで処理されます。
次の例は、test
モジュールを使用してテストを作成する方法を示しています。
test('同期通過テスト', t => {
// このテストは、例外をスローしないため、パスします。
assert.strictEqual(1, 1)
})
test('同期失敗テスト', t => {
// このテストは、例外をスローするため、失敗します。
assert.strictEqual(1, 2)
})
test('非同期通過テスト', async t => {
// このテストは、非同期関数が返すPromiseが解決され、拒否されないため、パスします。
assert.strictEqual(1, 1)
})
test('非同期失敗テスト', async t => {
// このテストは、非同期関数が返すPromiseが拒否されるため、失敗します。
assert.strictEqual(1, 2)
})
test('Promise を使用した失敗テスト', t => {
// Promise も直接使用できます。
return new Promise((resolve, reject) => {
setImmediate(() => {
reject(new Error('これはテストを失敗させます'))
})
})
})
test('コールバック通過テスト', (t, done) => {
// done() はコールバック関数です。setImmediate() が実行されると、引数なしで done() を呼び出します。
setImmediate(done)
})
test('コールバック失敗テスト', (t, done) => {
// setImmediate() が実行されると、Error オブジェクトを使用して done() が呼び出され、テストが失敗します。
setImmediate(() => {
done(new Error('コールバック失敗'))
})
})
テストに失敗があると、プロセスの終了コードが 1
に設定されます。
サブテスト
テストコンテキストのtest()
メソッドを使用すると、サブテストを作成できます。これにより、上位のテスト内にネストされたテストを作成できる階層的な方法でテストを構成できます。このメソッドは、最上位のtest()
関数と同様に動作します。次の例は、2 つのサブテストを持つ最上位のテストの作成を示しています。
test('トップレベルテスト', async t => {
await t.test('サブテスト1', t => {
assert.strictEqual(1, 1)
})
await t.test('サブテスト2', t => {
assert.strictEqual(2, 2)
})
})
この例では、await
を使用して、両方のサブテストが完了していることを確認しています。これは、スイート内で作成されたテストとは異なり、テストはサブテストの完了を待機しないため必要です。親テストが終了した時点で未処理のサブテストはキャンセルされ、失敗として扱われます。サブテストのいずれかが失敗すると、親テストも失敗します。
テストのスキップ
skip
オプションをテストに渡すか、次の例に示すようにテストコンテキストのskip()
メソッドを呼び出すことで、個々のテストをスキップできます。
// skipオプションが使用されていますが、メッセージは提供されていません。
test('skipオプション', { skip: true }, t => {
// このコードは実行されません。
})
// skipオプションが使用されており、メッセージが提供されています。
test('skipオプションとメッセージ', { skip: 'これはスキップされます' }, t => {
// このコードは実行されません。
})
test('skip()メソッド', t => {
// テストに追加のロジックが含まれている場合もここで返すようにしてください。
t.skip()
})
test('skip()メソッドとメッセージ', t => {
// テストに追加のロジックが含まれている場合もここで返すようにしてください。
t.skip('これはスキップされます')
})
TODO テスト
次の例に示すように、todo
オプションをテストに渡すか、テストコンテキストのtodo()
メソッドを呼び出すことで、個々のテストを不安定または未完成としてマークできます。これらのテストは、実装が保留中であるか、修正が必要なバグを表しています。TODO テストは実行されますが、テストの失敗として扱われず、そのためプロセスの終了コードに影響しません。テストが TODO とスキップの両方としてマークされている場合、TODO オプションは無視されます。
// todoオプションが使用されていますが、メッセージは提供されていません。
test('todoオプション', { todo: true }, t => {
// このコードは実行されますが、失敗として扱われません。
throw new Error('これはテストを失敗させません')
})
// todoオプションが使用されており、メッセージが提供されています。
test('todoオプションとメッセージ', { todo: 'これはTODOテストです' }, t => {
// このコードは実行されます。
})
test('todo()メソッド', t => {
t.todo()
})
test('todo()メソッドとメッセージ', t => {
t.todo('これはTODOテストであり、失敗として扱われません')
throw new Error('これはテストを失敗させません')
})
describe()
と it()
のエイリアス
スイートとテストは、describe()
関数と it()
関数を使って記述することもできます。describe()
は suite()
のエイリアスであり、it()
は test()
のエイリアスです。
describe('A thing', () => {
it('should work', () => {
assert.strictEqual(1, 1)
})
it('should be ok', () => {
assert.strictEqual(2, 2)
})
describe('a nested thing', () => {
it('should work', () => {
assert.strictEqual(3, 3)
})
})
})
describe()
と it()
は node:test
モジュールからインポートされます。
import { describe, it } from 'node:test'
const { describe, it } = require('node:test')
only
テスト
Node.js が --test-only
コマンドラインオプションで起動されている場合、またはテストの分離が無効になっている場合、実行するテストの選択されたサブセットに only
オプションを渡すことで、選択されたサブセットを除くすべてのテストをスキップできます。only
オプションが設定されているテストがある場合、すべてのサブテストも実行されます。スイートに only
オプションが設定されている場合、そのスイート内のすべてのテストが実行されますが、only
オプションが設定されている子孫がある場合は、それらのテストのみが実行されます。
サブテスト
を test()
/it()
内で使用する場合、選択されたサブセットのテストのみを実行するには、すべての祖先テストに only
オプションを付ける必要があります。
テストコンテキストの runOnly()
メソッドを使用して、サブテストレベルで同じ動作を実装できます。実行されないテストは、テストランナーの出力から省略されます。
// Node.js が --test-only コマンドラインオプションで実行されていると仮定します。
// スイートの 'only' オプションが設定されているため、これらのテストは実行されます。
test('this test is run', { only: true }, async t => {
// このテスト内では、すべてのサブテストがデフォルトで実行されます。
await t.test('running subtest')
// テストコンテキストを更新して、'only' オプションでサブテストを実行できます。
t.runOnly(true)
await t.test('this subtest is now skipped')
await t.test('this subtest is run', { only: true })
// コンテキストを元に戻して、すべてのテストを実行します。
t.runOnly(false)
await t.test('this subtest is now run')
// 明示的にこれらのテストを実行しません。
await t.test('skipped subtest 3', { only: false })
await t.test('skipped subtest 4', { skip: true })
})
// 'only' オプションが設定されていないため、このテストはスキップされます。
test('this test is not run', () => {
// このコードは実行されません。
throw new Error('fail')
})
describe('a suite', () => {
// 'only' オプションが設定されているため、このテストは実行されます。
it('this test is run', { only: true }, () => {
// このコードは実行されます。
})
it('this test is not run', () => {
// このコードは実行されません。
throw new Error('fail')
})
})
describe.only('a suite', () => {
// 'only' オプションが設定されているため、このテストは実行されます。
it('this test is run', () => {
// このコードは実行されます。
})
it('this test is run', () => {
// このコードは実行されます。
})
})
名前によるテストのフィルタリング
--test-name-pattern
コマンドラインオプションを使用すると、指定されたパターンに一致する名前のテストのみを実行でき、--test-skip-pattern
オプションを使用すると、指定されたパターンに一致する名前のテストをスキップできます。テスト名のパターンは、JavaScript の正規表現として解釈されます。ネストされたテストを実行するために、--test-name-pattern
と --test-skip-pattern
オプションは複数回指定できます。実行される各テストについて、beforeEach()
などの対応するテストフックも実行されます。実行されないテストは、テストランナーの出力から省略されます。
次のテストファイルの場合、--test-name-pattern="test [1-3]"
オプションで Node.js を起動すると、テストランナーは test 1
、test 2
、test 3
を実行します。test 1
がテスト名パターンに一致しなかった場合、そのサブテストは、パターンに一致していても実行されません。同じテストセットは、--test-name-pattern
を複数回渡すことによっても実行できます(例:--test-name-pattern="test 1"
、--test-name-pattern="test 2"
など)。
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')
})
テスト名パターンは、正規表現リテラルを使用して指定することもできます。これにより、正規表現フラグを使用できます。前の例では、--test-name-pattern="/test [4-5]/i"
(または --test-skip-pattern="/test [4-5]/i"
)で Node.js を起動すると、パターンは大文字と小文字を区別しないため、Test 4
と Test 5
に一致します。
パターンを使用して単一のテストに一致させるには、一意になるように、すべての祖先テスト名をスペースで区切って接頭辞を付けることができます。たとえば、次のテストファイルの場合:
describe('test 1', t => {
it('some test')
})
describe('test 2', t => {
it('some test')
})
--test-name-pattern="test 1 some test"
で Node.js を起動すると、test 1
の some test
のみに一致します。
テスト名パターンは、テストランナーが実行するファイルのセットを変更しません。
--test-name-pattern
と --test-skip-pattern
の両方が指定されている場合、テストは実行されるために両方の要件を満たす必要があります。
余分な非同期アクティビティ
テスト関数の実行が完了すると、テストの順序を維持しながら、できるだけ早く結果が報告されます。しかし、テスト関数自体よりも長く存続する非同期アクティビティをテスト関数が生成する可能性があります。テストランナーはこのタイプのアクティビティを処理しますが、それを考慮するためにテスト結果の報告を遅らせることはありません。
次の例では、2 つのsetImmediate()
操作が未処理の状態でテストが完了します。最初のsetImmediate()
は新しいサブテストを作成しようとします。親テストは既に終了して結果を出力しているので、新しいサブテストはすぐに失敗としてマークされ、後で<TestsStream>
に報告されます。
2 番目のsetImmediate()
はuncaughtException
イベントを作成します。完了したテストから発生したuncaughtException
とunhandledRejection
イベントは、test
モジュールによって失敗としてマークされ、<TestsStream>
によって最上位レベルで診断警告として報告されます。
test('a test that creates asynchronous activity', t => {
setImmediate(() => {
t.test('subtest that is created too late', t => {
throw new Error('error1')
})
})
setImmediate(() => {
throw new Error('error2')
})
// The test finishes after this line.
})
ウォッチモード
追加されたバージョン: v19.2.0, v18.13.0
[Stable: 1 - Experimental]
Stable: 1 Stability: 1 - Experimental
Node.js テストランナーは、--watch
フラグを渡すことでウォッチモードで実行できます。
node --test --watch
ウォッチモードでは、テストランナーはテストファイルとその依存関係の変更を監視します。変更が検出されると、テストランナーは変更の影響を受けたテストを再実行します。テストランナーはプロセスが終了するまで実行を続けます。
コマンドラインからのテストの実行
Node.js テストランナーは、--test
[/api/cli#--test]フラグを渡すことでコマンドラインから呼び出すことができます。
node --test
デフォルトでは、Node.js はこれらのパターンに一致するすべてのファイルを実行します。
**/*.test.{cjs,mjs,js}
**/*-test.{cjs,mjs,js}
**/*_test.{cjs,mjs,js}
**/test-*.{cjs,mjs,js}
**/test.{cjs,mjs,js}
**/test/**/*.{cjs,mjs,js}
--experimental-strip-types
が指定されている場合、以下の追加パターンが一致されます。
**/*.test.{cts,mts,ts}
**/*-test.{cts,mts,ts}
**/*_test.{cts,mts,ts}
**/test-*.{cts,mts,ts}
**/test.{cts,mts,ts}
**/test/**/*.{cts,mts,ts}
あるいは、以下に示すように、1 つ以上の glob パターンを Node.js コマンドの最後の引数として指定できます。glob パターンはglob(7)
の動作に従います。システム間での移植性を高めるために、glob パターンはコマンドラインで二重引用符で囲む必要があります。
node --test "**/*.test.js" "**/*.spec.js"
一致するファイルはテストファイルとして実行されます。テストファイルの実行に関する詳細は、テストランナー実行モデルセクションを参照してください。
テストランナーの実行モデル
プロセスレベルのテスト分離が有効になっている場合、一致する各テストファイルは別々の子プロセスで実行されます。一度に実行される子プロセスの最大数は、--test-concurrency
フラグで制御されます。子プロセスが終了コード 0 で終了した場合、テストは成功とみなされます。それ以外の場合は、テストは失敗とみなされます。テストファイルは Node.js によって実行可能である必要がありますが、内部でnode:test
モジュールを使用する必要はありません。
各テストファイルは、通常のスクリプトであるかのように実行されます。つまり、テストファイル自体がnode:test
を使用してテストを定義している場合、test()
のconcurrency
オプションの値に関係なく、それらのテストはすべて単一アプリケーションスレッド内で実行されます。
プロセスレベルのテスト分離が無効になっている場合、一致する各テストファイルはテストランナープロセスにインポートされます。すべてのテストファイルがロードされると、最上位レベルのテストがコンカレンシー 1 で実行されます。テストファイルはすべて同じコンテキスト内で実行されるため、分離が有効になっている場合とは不可能な方法でテストが相互に作用する可能性があります。たとえば、テストがグローバル状態に依存している場合、別のファイルに由来するテストによってその状態が変更される可能性があります。
コードカバレッジの収集
Node.js が--experimental-test-coverage
コマンドラインフラグで起動されると、コードカバレッジが収集され、すべてのテストが完了すると統計が報告されます。NODE_V8_COVERAGE
環境変数を使用してコードカバレッジディレクトリを指定した場合、生成された V8 カバレッジファイルはそのディレクトリに書き込まれます。デフォルトでは、Node.js コアモジュールとnode_modules/
ディレクトリ内のファイルはカバレッジレポートに含まれません。ただし、--test-coverage-include
フラグを使用して明示的に含めることができます。デフォルトでは、一致するすべてのテストファイルはカバレッジレポートから除外されます。除外は--test-coverage-exclude
フラグを使用してオーバーライドできます。カバレッジが有効になっている場合、カバレッジレポートは'test:coverage'
イベントを介してテストレポーターに送信されます。
次のコメント構文を使用して、一連の行でカバレッジを無効にすることができます。
/* node:coverage disable */
if (anAlwaysFalseCondition) {
// この分岐のコードは実行されませんが、行はカバレッジの目的で無視されます。'disable'コメントに続くすべての行は、対応する'enable'コメントが検出されるまで無視されます。
console.log('これは実行されません')
}
/* node:coverage enable */
指定された行数に対してカバレッジを無効にすることもできます。指定された行数後、カバレッジは自動的に再度有効になります。行数が明示的に指定されていない場合、1 行が無視されます。
/* node:coverage ignore next */
if (anAlwaysFalseCondition) {
console.log('これは実行されません')
}
/* node:coverage ignore next 3 */
if (anAlwaysFalseCondition) {
console.log('これは実行されません')
}
カバレッジレポーター
tap
レポーターとspec
レポーターは、カバレッジ統計のサマリーを出力します。また、lcov
レポーターは、詳細なカバレッジレポートとして使用できる lcov ファイルを作成します。
node --test --experimental-test-coverage --test-reporter=lcov --test-reporter-destination=lcov.info
- このレポーターはテスト結果を報告しません。
- このレポーターは、他のレポーターと併用するのが理想的です。
モッキング
node:test
モジュールは、トップレベルのmock
オブジェクトを介して、テスト中のモッキングをサポートしています。次の例では、2 つの数値を加算する関数のスパイを作成します。その後、このスパイを使用して、関数が期待通りに呼び出されたことをアサートします。
import assert from 'node:assert'
import { mock, test } from 'node:test'
test('spies on a function', () => {
const sum = mock.fn((a, b) => {
return a + b
})
assert.strictEqual(sum.mock.callCount(), 0)
assert.strictEqual(sum(3, 4), 7)
assert.strictEqual(sum.mock.callCount(), 1)
const call = sum.mock.calls[0]
assert.deepStrictEqual(call.arguments, [3, 4])
assert.strictEqual(call.result, 7)
assert.strictEqual(call.error, undefined)
// Reset the globally tracked mocks.
mock.reset()
})
'use strict'
const assert = require('node:assert')
const { mock, test } = require('node:test')
test('spies on a function', () => {
const sum = mock.fn((a, b) => {
return a + b
})
assert.strictEqual(sum.mock.callCount(), 0)
assert.strictEqual(sum(3, 4), 7)
assert.strictEqual(sum.mock.callCount(), 1)
const call = sum.mock.calls[0]
assert.deepStrictEqual(call.arguments, [3, 4])
assert.strictEqual(call.result, 7)
assert.strictEqual(call.error, undefined)
// Reset the globally tracked mocks.
mock.reset()
})
同じモッキング機能は、各テストのTestContext
オブジェクトにも公開されています。次の例では、TestContext
で公開されている API を使用して、オブジェクトメソッドのスパイを作成します。テストコンテキストを介したモッキングの利点は、テストが終了すると、テストランナーがすべてのモック機能を自動的に復元することです。
test('spies on an object method', t => {
const number = {
value: 5,
add(a) {
return this.value + a
},
}
t.mock.method(number, 'add')
assert.strictEqual(number.add.mock.callCount(), 0)
assert.strictEqual(number.add(3), 8)
assert.strictEqual(number.add.mock.callCount(), 1)
const call = number.add.mock.calls[0]
assert.deepStrictEqual(call.arguments, [3])
assert.strictEqual(call.result, 8)
assert.strictEqual(call.target, undefined)
assert.strictEqual(call.this, number)
})
タイマー
タイマーのモック化は、setInterval
やsetTimeout
などのタイマーの動作を、指定された時間間隔を実際に待つことなくシミュレートして制御するために、ソフトウェアテストで一般的に使用される手法です。
メソッドと機能の完全なリストについては、MockTimers
クラスを参照してください。
これにより、開発者は、時間依存の機能に対して、より信頼性が高く予測可能なテストを作成できます。
以下の例は、setTimeout
をモックする方法を示しています。.enable({ apis: ['setTimeout'] });
を使用すると、node:timersとnode:timers/promisesモジュール、および Node.js のグローバルコンテキストのsetTimeout
関数がモックされます。
注記: import { setTimeout } from 'node:timers'
などのデストラクチャリング関数は、現在この API ではサポートされていません。
import assert from 'node:assert'
import { mock, test } from 'node:test'
test('mocks setTimeout to be executed synchronously without having to actually wait for it', () => {
const fn = mock.fn()
// Optionally choose what to mock
mock.timers.enable({ apis: ['setTimeout'] })
setTimeout(fn, 9999)
assert.strictEqual(fn.mock.callCount(), 0)
// Advance in time
mock.timers.tick(9999)
assert.strictEqual(fn.mock.callCount(), 1)
// Reset the globally tracked mocks.
mock.timers.reset()
// If you call reset mock instance, it will also reset timers instance
mock.reset()
})
const assert = require('node:assert')
const { mock, test } = require('node:test')
test('mocks setTimeout to be executed synchronously without having to actually wait for it', () => {
const fn = mock.fn()
// Optionally choose what to mock
mock.timers.enable({ apis: ['setTimeout'] })
setTimeout(fn, 9999)
assert.strictEqual(fn.mock.callCount(), 0)
// Advance in time
mock.timers.tick(9999)
assert.strictEqual(fn.mock.callCount(), 1)
// Reset the globally tracked mocks.
mock.timers.reset()
// If you call reset mock instance, it will also reset timers instance
mock.reset()
})
同じモック機能は、各テストのTestContext
オブジェクトの mock プロパティにも公開されています。テストコンテキストを介してモック化することの利点は、テストが終了すると、テストランナーがすべてのモック化されたタイマー機能を自動的に復元することです。
import assert from 'node:assert'
import { test } from 'node:test'
test('mocks setTimeout to be executed synchronously without having to actually wait for it', context => {
const fn = context.mock.fn()
// Optionally choose what to mock
context.mock.timers.enable({ apis: ['setTimeout'] })
setTimeout(fn, 9999)
assert.strictEqual(fn.mock.callCount(), 0)
// Advance in time
context.mock.timers.tick(9999)
assert.strictEqual(fn.mock.callCount(), 1)
})
const assert = require('node:assert')
const { test } = require('node:test')
test('mocks setTimeout to be executed synchronously without having to actually wait for it', context => {
const fn = context.mock.fn()
// Optionally choose what to mock
context.mock.timers.enable({ apis: ['setTimeout'] })
setTimeout(fn, 9999)
assert.strictEqual(fn.mock.callCount(), 0)
// Advance in time
context.mock.timers.tick(9999)
assert.strictEqual(fn.mock.callCount(), 1)
})
日付
モックタイマー API では、Date
オブジェクトのモックも可能です。これは、時間依存の機能のテストや、Date.now()
などの内部カレンダー関数のシミュレーションに役立つ機能です。
日付の実装もMockTimers
クラスの一部です。メソッドと機能の完全なリストについては、そちらを参照してください。
注記: 日付とタイマーは、一緒にモックされた場合に依存関係を持ちます。つまり、Date
とsetTimeout
の両方をモックした場合、時間を進めると、単一の内部クロックをシミュレートするため、モックされた日付も進みます。
以下の例は、Date
オブジェクトをモックし、現在のDate.now()
値を取得する方法を示しています。
import assert from 'node:assert'
import { test } from 'node:test'
test('mocks the Date object', context => {
// Optionally choose what to mock
context.mock.timers.enable({ apis: ['Date'] })
// If not specified, the initial date will be based on 0 in the UNIX epoch
assert.strictEqual(Date.now(), 0)
// Advance in time will also advance the date
context.mock.timers.tick(9999)
assert.strictEqual(Date.now(), 9999)
})
const assert = require('node:assert')
const { test } = require('node:test')
test('mocks the Date object', context => {
// Optionally choose what to mock
context.mock.timers.enable({ apis: ['Date'] })
// If not specified, the initial date will be based on 0 in the UNIX epoch
assert.strictEqual(Date.now(), 0)
// Advance in time will also advance the date
context.mock.timers.tick(9999)
assert.strictEqual(Date.now(), 9999)
})
初期のエポックが設定されていない場合、初期日付は UNIX エポックの 0 に基づきます。これは、1970 年 1 月 1 日 00:00:00 UTC です。.enable()
メソッドにnow
プロパティを渡すことで、初期日付を設定できます。この値は、モックされたDate
オブジェクトの初期日付として使用されます。正の整数または別の Date オブジェクトのいずれかです。
import assert from 'node:assert'
import { test } from 'node:test'
test('mocks the Date object with initial time', context => {
// Optionally choose what to mock
context.mock.timers.enable({ apis: ['Date'], now: 100 })
assert.strictEqual(Date.now(), 100)
// Advance in time will also advance the date
context.mock.timers.tick(200)
assert.strictEqual(Date.now(), 300)
})
const assert = require('node:assert')
const { test } = require('node:test')
test('mocks the Date object with initial time', context => {
// Optionally choose what to mock
context.mock.timers.enable({ apis: ['Date'], now: 100 })
assert.strictEqual(Date.now(), 100)
// Advance in time will also advance the date
context.mock.timers.tick(200)
assert.strictEqual(Date.now(), 300)
})
.setTime()
メソッドを使用して、モックされた日付を手動で別の時間に変更できます。このメソッドは正の整数のみを受け付けます。
注記: このメソッドは、新しい時間から過去にあるモックされたタイマーを実行します。
以下の例では、モックされた日付の新しい時間を設定しています。
import assert from 'node:assert'
import { test } from 'node:test'
test('sets the time of a date object', context => {
// Optionally choose what to mock
context.mock.timers.enable({ apis: ['Date'], now: 100 })
assert.strictEqual(Date.now(), 100)
// Advance in time will also advance the date
context.mock.timers.setTime(1000)
context.mock.timers.tick(200)
assert.strictEqual(Date.now(), 1200)
})
const assert = require('node:assert')
const { test } = require('node:test')
test('sets the time of a date object', context => {
// Optionally choose what to mock
context.mock.timers.enable({ apis: ['Date'], now: 100 })
assert.strictEqual(Date.now(), 100)
// Advance in time will also advance the date
context.mock.timers.setTime(1000)
context.mock.timers.tick(200)
assert.strictEqual(Date.now(), 1200)
})
過去に実行するように設定されているタイマーがある場合、.tick()
メソッドが呼び出されたかのように実行されます。これは、すでに過去にある時間依存の機能をテストする場合に役立ちます。
import assert from 'node:assert'
import { test } from 'node:test'
test('runs timers as setTime passes ticks', context => {
// Optionally choose what to mock
context.mock.timers.enable({ apis: ['setTimeout', 'Date'] })
const fn = context.mock.fn()
setTimeout(fn, 1000)
context.mock.timers.setTime(800)
// Timer is not executed as the time is not yet reached
assert.strictEqual(fn.mock.callCount(), 0)
assert.strictEqual(Date.now(), 800)
context.mock.timers.setTime(1200)
// Timer is executed as the time is now reached
assert.strictEqual(fn.mock.callCount(), 1)
assert.strictEqual(Date.now(), 1200)
})
const assert = require('node:assert')
const { test } = require('node:test')
test('runs timers as setTime passes ticks', context => {
// Optionally choose what to mock
context.mock.timers.enable({ apis: ['setTimeout', 'Date'] })
const fn = context.mock.fn()
setTimeout(fn, 1000)
context.mock.timers.setTime(800)
// Timer is not executed as the time is not yet reached
assert.strictEqual(fn.mock.callCount(), 0)
assert.strictEqual(Date.now(), 800)
context.mock.timers.setTime(1200)
// Timer is executed as the time is now reached
assert.strictEqual(fn.mock.callCount(), 1)
assert.strictEqual(Date.now(), 1200)
})
.runAll()
を使用すると、キューにあるすべてのタイマーを実行します。これにより、時間が経過したかのように、実行された最後のタイマーの時間にモックされた日付も進みます。
import assert from 'node:assert'
import { test } from 'node:test'
test('runs timers as setTime passes ticks', context => {
// Optionally choose what to mock
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()
// All timers are executed as the time is now reached
assert.strictEqual(fn.mock.callCount(), 3)
assert.strictEqual(Date.now(), 3000)
})
const assert = require('node:assert')
const { test } = require('node:test')
test('runs timers as setTime passes ticks', context => {
// Optionally choose what to mock
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()
// All timers are executed as the time is now reached
assert.strictEqual(fn.mock.callCount(), 3)
assert.strictEqual(Date.now(), 3000)
})
スナップショットテスト
スナップショットテストでは、任意の値を文字列値にシリアライズし、一連の既知の良好な値と比較できます。既知の良好な値はスナップショットと呼ばれ、スナップショットファイルに保存されます。スナップショットファイルはテストランナーによって管理されますが、デバッグを容易にするために人間が読めるように設計されています。ベストプラクティスとして、スナップショットファイルはテストファイルと一緒にソースコード管理にチェックインします。
スナップショットファイルは、--test-update-snapshots
コマンドラインフラグを使用して Node.js を起動することで生成されます。各テストファイルごとに個別のスナップショットファイルが生成されます。デフォルトでは、スナップショットファイルの名前は、.snapshot
ファイル拡張子付きのテストファイルと同じになります。この動作は、snapshot.setResolveSnapshotPath()
関数を使用して構成できます。各スナップショットアサーションは、スナップショットファイル内のエクスポートに対応します。
スナップショットテストの例を以下に示します。このテストを初めて実行すると、対応するスナップショットファイルが存在しないため失敗します。
// test.js
suite('suite of snapshot tests', () => {
test('snapshot test', t => {
t.assert.snapshot({ value1: 1, value2: 2 })
t.assert.snapshot(5)
})
})
--test-update-snapshots
を使用してテストファイルを実行することで、スナップショットファイルを生成します。テストはパスし、テストファイルと同じディレクトリにtest.js.snapshot
という名前のファイルが作成されます。スナップショットファイルの内容を以下に示します。各スナップショットは、テストの完全名と、同じテスト内のスナップショットを区別するためのカウンターによって識別されます。
exports[`suite of snapshot tests > snapshot test 1`] = `
{
"value1": 1,
"value2": 2
}
`
exports[`suite of snapshot tests > snapshot test 2`] = `
5
`
スナップショットファイルが作成されたら、--test-update-snapshots
フラグなしでテストを再度実行します。これでテストはパスするはずです。
テストレポーター
[履歴]
バージョン | 変更内容 |
---|---|
v19.9.0, v18.17.0 | レポーターは node:test/reporters で公開されるようになりました。 |
v19.6.0, v18.15.0 | 追加: v19.6.0, v18.15.0 |
node:test
モジュールは、テストランナーで特定のレポーターを使用するために --test-reporter
フラグを渡すことをサポートしています。
以下の組み込みレポーターがサポートされています。
spec
spec
レポーターは、テスト結果を人間が読める形式で出力します。これはデフォルトのレポーターです。tap
tap
レポーターは、TAP 形式でテスト結果を出力します。dot
dot
レポーターは、コンパクトな形式でテスト結果を出力します。合格したテストは.
で、失敗したテストはX
で表されます。junit
junit レポーターは、JUnit XML 形式でテスト結果を出力します。lcov
lcov
レポーターは、--experimental-test-coverage
フラグと併用すると、テストカバレッジを出力します。
これらのレポーターの正確な出力は、Node.js のバージョン間で変更される可能性があり、プログラム的に依存すべきではありません。テストランナーの出力にプログラムからアクセスする必要がある場合は、<TestsStream>
によって発行されるイベントを使用してください。
レポーターは node:test/reporters
モジュールを介して利用できます。
import { tap, spec, dot, junit, lcov } from 'node:test/reporters'
const { tap, spec, dot, junit, lcov } = require('node:test/reporters')
カスタムレポーター
--test-reporter
を使用して、カスタムレポーターへのパスを指定できます。カスタムレポーターは、stream.compose で受け入れられる値をエクスポートするモジュールです。レポーターは、<TestsStream>
によって発行されるイベントを変換する必要があります。
<stream.Transform>
を使用したカスタムレポーターの例:
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} dequeued`)
break
case 'test:enqueue':
callback(null, `test ${event.data.name} enqueued`)
break
case 'test:watch:drained':
callback(null, 'test watch queue drained')
break
case 'test:start':
callback(null, `test ${event.data.name} started`)
break
case 'test:pass':
callback(null, `test ${event.data.name} passed`)
break
case 'test:fail':
callback(null, `test ${event.data.name} failed`)
break
case 'test:plan':
callback(null, 'test plan')
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, `total line count: ${totalLineCount}\n`)
break
}
}
},
})
export default customReporter
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} dequeued`)
break
case 'test:enqueue':
callback(null, `test ${event.data.name} enqueued`)
break
case 'test:watch:drained':
callback(null, 'test watch queue drained')
break
case 'test:start':
callback(null, `test ${event.data.name} started`)
break
case 'test:pass':
callback(null, `test ${event.data.name} passed`)
break
case 'test:fail':
callback(null, `test ${event.data.name} failed`)
break
case 'test:plan':
callback(null, 'test plan')
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, `total line count: ${totalLineCount}\n`)
break
}
}
},
})
module.exports = customReporter
ジェネレーター関数を使用したカスタムレポーターの例:
export default async function* customReporter(source) {
for await (const event of source) {
switch (event.type) {
case 'test:dequeue':
yield `test ${event.data.name} dequeued\n`
break
case 'test:enqueue':
yield `test ${event.data.name} enqueued\n`
break
case 'test:watch:drained':
yield 'test watch queue drained\n'
break
case 'test:start':
yield `test ${event.data.name} started\n`
break
case 'test:pass':
yield `test ${event.data.name} passed\n`
break
case 'test:fail':
yield `test ${event.data.name} failed\n`
break
case 'test:plan':
yield 'test plan\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 `total line count: ${totalLineCount}\n`
break
}
}
}
}
module.exports = async function* customReporter(source) {
for await (const event of source) {
switch (event.type) {
case 'test:dequeue':
yield `test ${event.data.name} dequeued\n`
break
case 'test:enqueue':
yield `test ${event.data.name} enqueued\n`
break
case 'test:watch:drained':
yield 'test watch queue drained\n'
break
case 'test:start':
yield `test ${event.data.name} started\n`
break
case 'test:pass':
yield `test ${event.data.name} passed\n`
break
case 'test:fail':
yield `test ${event.data.name} failed\n`
break
case 'test:plan':
yield 'test plan\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 `total line count: ${totalLineCount}\n`
break
}
}
}
}
--test-reporter
に提供される値は、JavaScript コードの import()
で使用されるものと同様の文字列、または --import
に提供される値である必要があります。
複数のレポーター
--test-reporter
フラグは複数回指定して、複数のフォーマットでテスト結果をレポートできます。この場合、--test-reporter-destination
を使用して、各レポーターの出力先を指定する必要があります。出力先は stdout
、stderr
、またはファイルパスです。レポーターと出力先は、指定された順序に従ってペアになります。
次の例では、spec
レポーターは stdout
に出力され、dot
レポーターは file.txt
に出力されます。
node --test-reporter=spec --test-reporter=dot --test-reporter-destination=stdout --test-reporter-destination=file.txt
レポーターを 1 つだけ指定した場合、出力先が明示的に指定されていない限り、出力先は stdout
になります。
run([options])
[履歴]
バージョン | 変更 |
---|---|
v23.0.0 | cwd オプションを追加 |
v23.0.0 | カバレッジオプションを追加 |
v22.8.0 | isolation オプションを追加 |
v22.6.0 | globPatterns オプションを追加 |
v22.0.0, v20.14.0 | forceExit オプションを追加 |
v20.1.0, v18.17.0 | testNamePatterns オプションを追加 |
v18.9.0, v16.19.0 | v18.9.0、v16.19.0 で追加 |
options
<Object> テスト実行の構成オプション。次のプロパティがサポートされています。concurrency
<number> | <boolean> 数値を指定すると、その数のテストプロセスが並列で実行されます。各プロセスは 1 つのテストファイルに対応します。true
の場合、os.availableParallelism() - 1
個のテストファイルが並列で実行されます。false
の場合、一度に 1 つのテストファイルしか実行されません。デフォルト:false
。cwd
: <string> テストランナーが使用する現在の作業ディレクトリを指定します。テストランナーの実行モデルに従ってファイルを解決するためのベースパスとして機能します。デフォルト:process.cwd()
。files
: <Array> 実行するファイルのリストを含む配列。デフォルト: テストランナーの実行モデルからの一致するファイル。forceExit
: <boolean> イベントループがアクティブなままであっても、既知のすべてのテストの実行が終了したら、テストランナーがプロセスを終了するように構成します。デフォルト:false
。globPatterns
: <Array> テストファイルと一致させる glob パターンのリストを含む配列。このオプションはfiles
と同時に使用できません。デフォルト: テストランナーの実行モデルからの一致するファイル。inspectPort
<number> | <Function> テスト子プロセスのインスペクターポートを設定します。これは数値、または引数を引数として受け取り数値を返す関数にすることができます。nullish な値が提供された場合、各プロセスは主プロセスのprocess.debugPort
から増分された独自のポートを取得します。isolation
オプションが'none'
に設定されている場合、子プロセスは生成されないため、このオプションは無視されます。デフォルト:undefined
。isolation
<string> テストの分離の種類を構成します。'process'
に設定すると、各テストファイルは別々の子プロセスで実行されます。'none'
に設定すると、すべてのテストファイルが現在のプロセスで実行されます。デフォルト:'process'
。only
: <boolean> 真理値の場合、テストコンテキストはonly
オプションが設定されているテストのみを実行します。setup
<Function>TestsStream
インスタンスを受け取る関数で、テストが実行される前にリスナーを設定するために使用できます。デフォルト:undefined
。execArgv
<Array> サブプロセスの生成時にnode
実行可能ファイルに渡す CLI フラグの配列。isolation
が'none'
の場合、このオプションは効果がありません。デフォルト:[]
argv
<Array> サブプロセスの生成時に各テストファイルに渡す CLI フラグの配列。isolation
が'none'
の場合、このオプションは効果がありません。デフォルト:[]
。signal
<AbortSignal> 実行中のテストの実行を中止できます。testNamePatterns
<string> | <RegExp> | <Array> 文字列、正規表現、または正規表現の配列で、指定されたパターンと一致する名前のテストのみを実行するために使用できます。テスト名パターンは JavaScript 正規表現として解釈されます。実行される各テストについて、beforeEach()
などの対応するテストフックも実行されます。デフォルト:undefined
。testSkipPatterns
<string> | <RegExp> | <Array> 文字列、正規表現、または正規表現の配列で、指定されたパターンと一致する名前のテストの実行を除外するために使用できます。テスト名パターンは JavaScript 正規表現として解釈されます。実行される各テストについて、beforeEach()
などの対応するテストフックも実行されます。デフォルト:undefined
。timeout
<number> テスト実行が失敗するまでのミリ秒数。指定されていない場合、サブテストは親からこの値を継承します。デフォルト:Infinity
。watch
<boolean> ウォッチモードで実行するかどうか。デフォルト:false
。shard
<Object> 特定のシャードでテストを実行します。デフォルト:undefined
。index
<number> 実行するシャードのインデックスを指定する、1 から\<total\>
の間の正の整数です。このオプションは必須です。total
<number> テストファイルを分割するシャードの総数を指定する正の整数です。このオプションは必須です。coverageExcludeGlobs
<string> | <Array> glob パターンを使用して、絶対パスと相対パスの両方に一致する特定のファイルをコードカバレッジから除外します。このプロパティは、coverage
がtrue
に設定されている場合にのみ適用されます。coverageExcludeGlobs
とcoverageIncludeGlobs
の両方が提供されている場合、ファイルはカバレッジレポートに含めるために両方の条件を満たす必要があります。デフォルト:undefined
。coverageIncludeGlobs
<string> | <Array> glob パターンを使用して、絶対パスと相対パスの両方に一致する特定のファイルをコードカバレッジに含めます。このプロパティは、coverage
がtrue
に設定されている場合にのみ適用されます。coverageExcludeGlobs
とcoverageIncludeGlobs
の両方が提供されている場合、ファイルはカバレッジレポートに含めるために両方の条件を満たす必要があります。デフォルト:undefined
。lineCoverage
<number> カバレッジされた行の最小パーセンテージを要求します。コードカバレッジが指定されたしきい値に達しない場合、プロセスはコード1
で終了します。デフォルト:0
。branchCoverage
<number> カバレッジされたブランチの最小パーセンテージを要求します。コードカバレッジが指定されたしきい値に達しない場合、プロセスはコード1
で終了します。デフォルト:0
。functionCoverage
<number> カバレッジされた関数の最小パーセンテージを要求します。コードカバレッジが指定されたしきい値に達しない場合、プロセスはコード1
で終了します。デフォルト:0
。
戻り値: <TestsStream>
注: shard
は、さまざまな環境にわたる大規模な実行に最適な、マシンまたはプロセス間でのテスト実行を水平方向に並列化するために使用されます。ファイルの変更時にテストを自動的に再実行することで、迅速なコード反復に最適化されたwatch
モードとは互換性がありません。
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)
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])
追加:v22.0.0, v20.13.0
name
<string> テスト結果を報告する際に表示されるスイートの名前。デフォルト:fn
のname
プロパティ、またはfn
に名前がない場合は'<anonymous>'
。options
<Object> スイートのオプション設定。test([name][, options][, fn])
と同じオプションをサポートします。fn
<Function> | <AsyncFunction> ネストされたテストとスイートを宣言するスイート関数。この関数の最初の引数はSuiteContext
オブジェクトです。デフォルト: 何もしない関数。- 戻り値: <Promise>
undefined
で即座に解決されます。
suite()
関数は node:test
モジュールからインポートされます。
suite.skip([name][, options][, fn])
追加:v22.0.0, v20.13.0
スイートをスキップするための省略形。suite([name], { skip: true }[, fn])
と同じです。
suite.todo([name][, options][, fn])
追加:v22.0.0, v20.13.0
スイートを TODO
としてマークするための省略形。suite([name], { todo: true }[, fn])
と同じです。
suite.only([name][, options][, fn])
追加:v22.0.0, v20.13.0
スイートを only
としてマークするための省略形。suite([name], { only: true }[, fn])
と同じです。
test([name][, options][, fn])
[履歴]
バージョン | 変更 |
---|---|
v20.2.0, v18.17.0 | skip 、todo 、only の省略形を追加 |
v18.8.0, v16.18.0 | signal オプションを追加 |
v18.7.0, v16.17.0 | timeout オプションを追加 |
v18.0.0, v16.17.0 | 追加 |
name
<string> テスト結果を報告する際に表示されるテストの名前。デフォルト:fn
のname
プロパティ、またはfn
に名前がない場合は'<anonymous>'
。options
<Object> テストの設定オプション。以下のプロパティをサポートします。concurrency
<number> | <boolean> 数値を指定すると、アプリケーションスレッド内でその数のテストが並列に実行されます。true
の場合、スケジュールされた非同期テストはすべてスレッド内で同時に実行されます。false
の場合、一度に 1 つのテストしか実行されません。指定しない場合、サブテストはこの値を親から継承します。デフォルト:false
。only
<boolean> 真理値の場合、テストコンテキストがonly
テストを実行するように設定されていると、このテストが実行されます。それ以外の場合は、テストはスキップされます。デフォルト:false
。signal
<AbortSignal> 実行中のテストの中断を許可します。skip
<boolean> | <string> 真理値の場合、テストはスキップされます。文字列を指定すると、その文字列がテスト結果にテストスキップの理由として表示されます。デフォルト:false
。todo
<boolean> | <string> 真理値の場合、テストはTODO
としてマークされます。文字列を指定すると、その文字列がテスト結果にテストがTODO
である理由として表示されます。デフォルト:false
。timeout
<number> テストが完了するまでに許容されるミリ秒数。指定しない場合、サブテストはこの値を親から継承します。デフォルト:Infinity
。plan
<number> テストで実行されるアサーションとサブテストの数。テストで実行されるアサーションの数が計画で指定された数と一致しない場合、テストは失敗します。デフォルト:undefined
。
fn
<Function> | <AsyncFunction> テスト対象の関数。この関数の最初の引数はTestContext
オブジェクトです。テストがコールバックを使用する場合、コールバック関数は 2 番目の引数として渡されます。デフォルト: 何もしない関数。戻り値: <Promise> テストが完了すると
undefined
で解決されます。または、テストがスイート内で実行される場合はすぐに解決されます。
test()
関数は test
モジュールからインポートされた値です。この関数の各呼び出しにより、テストが <TestsStream> に報告されます。
fn
引数に渡される TestContext
オブジェクトを使用して、現在のテストに関連するアクションを実行できます。これには、テストのスキップ、追加の診断情報の追加、またはサブテストの作成などが含まれます。
test()
は、テストが完了すると解決される Promise
を返します。test()
がスイート内で呼び出された場合、すぐに解決されます。トップレベルテストの場合、戻り値は通常破棄できます。ただし、サブテストの戻り値は、親テストが先に終了してサブテストをキャンセルするのを防ぐために使用してください。次の例を参照してください。
test('トップレベルテスト', async t => {
// 次のサブテストの setTimeout() は、次の行で 'await' を削除した場合、親テストよりも長生きする可能性があります。親テストが完了すると、未処理のサブテストはすべてキャンセルされます。
await t.test('長時間実行されるサブテスト', async t => {
return new Promise((resolve, reject) => {
setTimeout(resolve, 1000)
})
})
})
timeout
オプションを使用して、timeout
ミリ秒より長くかかるとテストを失敗させることができます。ただし、実行中のテストがアプリケーションスレッドをブロックし、スケジュールされたキャンセルを防ぐ可能性があるため、テストをキャンセルするための信頼できるメカニズムではありません。
test.skip([name][, options][, fn])
テストをスキップするための省略記法。test([name], { skip: true }[, fn])
と同じです。
test.todo([name][, options][, fn])
テストをTODO
としてマークするための省略記法。test([name], { todo: true }[, fn])
と同じです。
test.only([name][, options][, fn])
テストをonly
としてマークするための省略記法。test([name], { only: true }[, fn])
と同じです。
describe([name][, options][, fn])
suite()
のエイリアスです。
describe()
関数はnode:test
モジュールからインポートされます。
describe.skip([name][, options][, fn])
スイートをスキップするための省略記法。describe([name], { skip: true }[, fn])
と同じです。
describe.todo([name][, options][, fn])
スイートをTODO
としてマークするための省略記法。describe([name], { todo: true }[, fn])
と同じです。
describe.only([name][, options][, fn])
追加されたバージョン: v19.8.0, v18.15.0
スイートをonly
としてマークするための省略記法。describe([name], { only: true }[, fn])
と同じです。
it([name][, options][, fn])
[履歴]
バージョン | 変更 |
---|---|
v19.8.0, v18.16.0 | it() の呼び出しは、test() の呼び出しと同等になりました。 |
v18.6.0, v16.17.0 | 追加されたバージョン: v18.6.0, v16.17.0 |
test()
のエイリアスです。
it()
関数はnode:test
モジュールからインポートされます。
it.skip([name][, options][, fn])
テストをスキップするための省略記法。it([name], { skip: true }[, fn])
と同じです。
it.todo([name][, options][, fn])
テストをTODO
としてマークするための省略記法。it([name], { todo: true }[, fn])
と同じです。
it.only([name][, options][, fn])
追加されたバージョン: v19.8.0, v18.15.0
テストをonly
としてマークするための省略記法。it([name], { only: true }[, fn])
と同じです。
before([fn][, options])
追加: v18.8.0, v16.18.0
fn
<Function> | <AsyncFunction> フック関数。フックがコールバックを使用する場合、コールバック関数は第二引数として渡されます。デフォルト: 何もしない関数。options
<Object> フックの構成オプション。以下のプロパティがサポートされています。signal
<AbortSignal> 実行中のフックの中断を許可します。timeout
<number> フックが失敗するまでのミリ秒数。指定しない場合、サブテストは親からこの値を継承します。デフォルト:Infinity
。
この関数は、スイートを実行する前に実行されるフックを作成します。
describe('tests', async () => {
before(() => console.log('about to run some test'))
it('is a subtest', () => {
assert.ok('some relevant assertion here')
})
})
after([fn][, options])
追加: v18.8.0, v16.18.0
fn
<Function> | <AsyncFunction> フック関数。フックがコールバックを使用する場合、コールバック関数は第二引数として渡されます。デフォルト: 何もしない関数。options
<Object> フックの構成オプション。以下のプロパティがサポートされています。signal
<AbortSignal> 実行中のフックの中断を許可します。timeout
<number> フックが失敗するまでのミリ秒数。指定しない場合、サブテストは親からこの値を継承します。デフォルト:Infinity
。
この関数は、スイートを実行した後に実行されるフックを作成します。
describe('tests', async () => {
after(() => console.log('finished running tests'))
it('is a subtest', () => {
assert.ok('some relevant assertion here')
})
})
注記: スイート内のテストが失敗した場合でも、after
フックは確実に実行されます。
beforeEach([fn][, options])
追加: v18.8.0, v16.18.0
fn
<Function> | <AsyncFunction> フック関数。フックがコールバックを使用する場合、コールバック関数は第 2 引数として渡されます。デフォルト: 何もしない関数。options
<Object> フックの構成オプション。以下のプロパティがサポートされています。signal
<AbortSignal> 実行中のフックの中断を許可します。timeout
<number> フックが失敗するまでのミリ秒数。指定しない場合、サブテストは親からこの値を継承します。デフォルト:Infinity
。
この関数は、現在のスイート内の各テストの前に実行されるフックを作成します。
describe('tests', async () => {
beforeEach(() => console.log('about to run a test'))
it('is a subtest', () => {
assert.ok('some relevant assertion here')
})
})
afterEach([fn][, options])
追加: v18.8.0, v16.18.0
fn
<Function> | <AsyncFunction> フック関数。フックがコールバックを使用する場合、コールバック関数は第 2 引数として渡されます。デフォルト: 何もしない関数。options
<Object> フックの構成オプション。以下のプロパティがサポートされています。signal
<AbortSignal> 実行中のフックの中断を許可します。timeout
<number> フックが失敗するまでのミリ秒数。指定しない場合、サブテストは親からこの値を継承します。デフォルト:Infinity
。
この関数は、現在のスイート内の各テストの後で実行されるフックを作成します。afterEach()
フックは、テストが失敗した場合でも実行されます。
describe('tests', async () => {
afterEach(() => console.log('finished running a test'))
it('is a subtest', () => {
assert.ok('some relevant assertion here')
})
})
snapshot
追加バージョン: v22.3.0
現在のプロセスにおけるデフォルトのスナップショット設定を構成するために使用されるメソッドを持つオブジェクトです。共通の構成コードを--require
または--import
でプリロードされたモジュールに配置することで、すべてのファイルに同じ構成を適用できます。
snapshot.setDefaultSnapshotSerializers(serializers)
追加バージョン: v22.3.0
serializers
<Array> スナップショットテストのデフォルトのシリアライザとして使用される同期関数の配列。
この関数は、テストランナーで使用されるデフォルトのシリアライゼーションメカニズムをカスタマイズするために使用されます。デフォルトでは、テストランナーは提供された値に対してJSON.stringify(value, null, 2)
を呼び出すことでシリアライゼーションを実行します。JSON.stringify()
には、循環構造とサポートされるデータ型に関する制限があります。より堅牢なシリアライゼーションメカニズムが必要な場合は、この関数を使用する必要があります。
snapshot.setResolveSnapshotPath(fn)
追加バージョン: v22.3.0
fn
<Function> スナップショットファイルの場所を計算するために使用される関数。この関数は、テストファイルのパスを唯一の引数として受け取ります。テストがファイルに関連付けられていない場合(REPL など)、入力は未定義です。fn()
は、スナップショットファイルの場所を指定する文字列を返す必要があります。
この関数は、スナップショットテストに使用されるスナップショットファイルの場所をカスタマイズするために使用されます。デフォルトでは、スナップショットファイル名は、エントリポイントファイル名と同じで、.snapshot
ファイル拡張子が付きます。
クラス: MockFunctionContext
追加: v19.1.0, v18.13.0
MockFunctionContext
クラスは、MockTracker
API を介して作成されたモックの動作を検査または操作するために使用されます。
ctx.calls
追加: v19.1.0, v18.13.0
モックへの呼び出しを追跡するために使用される内部配列のコピーを返すゲッターです。配列内の各エントリは、次のプロパティを持つオブジェクトです。
arguments
<Array> モック関数に渡された引数の配列。error
<any> モック関数がスローされた場合、このプロパティにはスローされた値が含まれます。デフォルト:undefined
。result
<any> モック関数によって返された値。stack
<Error> モック関数の呼び出し元を特定するために使用できるスタックを持つError
オブジェクト。target
<Function> | <undefined> モック関数がコンストラクタである場合、このフィールドには構築されているクラスが含まれます。それ以外の場合はundefined
になります。this
<any> モック関数のthis
値。
ctx.callCount()
追加: v19.1.0, v18.13.0
- 戻り値: <integer> このモックが呼び出された回数。
この関数は、このモックが呼び出された回数を返します。ctx.calls
は内部の呼び出し追跡配列のコピーを作成するゲッターであるため、ctx.calls.length
をチェックするよりも、この関数は効率的です。
ctx.mockImplementation(implementation)
追加日時: v19.1.0, v18.13.0
implementation
<Function> | <AsyncFunction> モックの新しい実装として使用される関数。
この関数は、既存のモックの動作を変更するために使用されます。
次の例では、t.mock.fn()
を使用してモック関数を生成し、モック関数を呼び出し、その後モックの実装を別の関数に変更します。
test('changes a mock behavior', 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])
追加日時: v19.1.0, v18.13.0
implementation
<Function> | <AsyncFunction>onCall
で指定された呼び出し回数に対してモックの実装として使用される関数。onCall
<integer>implementation
を使用する呼び出し回数。指定された呼び出しが既に発生している場合、例外がスローされます。デフォルト: 次の呼び出しの数。
この関数は、単一の呼び出しに対して既存のモックの動作を変更するために使用されます。呼び出しonCall
が発生すると、モックはmockImplementationOnce()
が呼び出されなかった場合に使用していた動作に戻ります。
次の例では、t.mock.fn()
を使用してモック関数を生成し、モック関数を呼び出し、次の呼び出しに対してモックの実装を別の関数に変更し、その後以前の動作を再開します。
test('changes a mock behavior once', 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()
追加: v19.3.0, v18.13.0
モック関数の呼び出し履歴をリセットします。
ctx.restore()
追加: v19.1.0, v18.13.0
モック関数の動作を元の動作にリセットします。この関数を呼び出した後も、モックは使用できます。
クラス: MockModuleContext
追加: v22.3.0, v20.18.0
MockModuleContext
クラスは、MockTracker
API を介して作成されたモジュールモックの動作を操作するために使用されます。
ctx.restore()
追加: v22.3.0, v20.18.0
モックモジュールの動作をリセットします。
クラス: MockTracker
追加: v19.1.0, v18.13.0
MockTracker
クラスは、モック機能の管理に使用されます。テストランナーモジュールは、MockTracker
インスタンスであるトップレベルのmock
エクスポートを提供します。各テストは、テストコンテキストのmock
プロパティを介して独自のMockTracker
インスタンスも提供します。
mock.fn([original[, implementation]][, options])
追加: v19.1.0, v18.13.0
original
<Function> | <AsyncFunction> モックを作成するオプションの関数。デフォルト: 何もしない関数。implementation
<Function> | <AsyncFunction>original
のモック実装として使用されるオプションの関数。これは、特定の回数呼び出された場合に 1 つの動作を示し、その後original
の動作を復元するモックを作成する場合に役立ちます。デフォルト:original
で指定された関数。options
<Object> モック関数のオプションの構成オプション。次のプロパティがサポートされています。times
<integer> モックがimplementation
の動作を使用する回数。モック関数がtimes
回呼び出されると、自動的にoriginal
の動作が復元されます。この値は 0 より大きい整数である必要があります。デフォルト:Infinity
。
戻り値: <Proxy> モック関数。モック関数には特別な
mock
プロパティが含まれており、これはMockFunctionContext
のインスタンスであり、モック関数の動作の検査と変更に使用できます。
この関数は、モック関数を作成するために使用されます。
次の例では、各呼び出しでカウンタを 1 ずつインクリメントするモック関数を作成します。times
オプションを使用して、最初の 2 回の呼び出しではカウンタに 1 ではなく 2 を追加するようにモックの動作を変更します。
test('mocks a counting function', t => {
let cnt = 0
function addOne() {
cnt++
return cnt
}
function addTwo() {
cnt += 2
return cnt
}
const fn = t.mock.fn(addOne, addTwo, { times: 2 })
assert.strictEqual(fn(), 2)
assert.strictEqual(fn(), 4)
assert.strictEqual(fn(), 5)
assert.strictEqual(fn(), 6)
})
mock.getter(object, methodName[, implementation][, options])
追加: v19.3.0, v18.13.0
この関数は、options.getter
をtrue
に設定したMockTracker.method
のシンタックスシュガーです。
mock.method(object, methodName[, implementation][, options])
追加: v19.1.0, v18.13.0
object
<Object> モック対象となるメソッドを持つオブジェクト。methodName
<string> | <symbol> モックするobject
上のメソッドの識別子。object[methodName]
が関数でない場合、エラーがスローされます。implementation
<Function> | <AsyncFunction>object[methodName]
のモック実装として使用されるオプションの関数。デフォルト:object[methodName]
で指定された元のメソッド。options
<Object> モックメソッドのオプションの構成オプション。以下のプロパティがサポートされています。getter
<boolean>true
の場合、object[methodName]
はゲッターとして扱われます。このオプションはsetter
オプションと併用できません。デフォルト: false。setter
<boolean>true
の場合、object[methodName]
はセッターとして扱われます。このオプションはgetter
オプションと併用できません。デフォルト: false。times
<integer> モックがimplementation
の動作を使用する回数。モックメソッドがtimes
回呼び出されると、元の動作が自動的に復元されます。この値は 0 より大きい整数である必要があります。デフォルト:Infinity
。
戻り値: <Proxy> モックされたメソッド。モックされたメソッドには特別な
mock
プロパティが含まれており、これはMockFunctionContext
のインスタンスであり、モックメソッドの動作の検査と変更に使用できます。
この関数は、既存のオブジェクトメソッドにモックを作成するために使用されます。次の例は、既存のオブジェクトメソッドにモックを作成する方法を示しています。
test('spies on an object method', t => {
const number = {
value: 5,
subtract(a) {
return this.value - a
},
}
t.mock.method(number, 'subtract')
assert.strictEqual(number.subtract.mock.callCount(), 0)
assert.strictEqual(number.subtract(3), 2)
assert.strictEqual(number.subtract.mock.callCount(), 1)
const call = number.subtract.mock.calls[0]
assert.deepStrictEqual(call.arguments, [3])
assert.strictEqual(call.result, 2)
assert.strictEqual(call.error, undefined)
assert.strictEqual(call.target, undefined)
assert.strictEqual(call.this, number)
})
mock.module(specifier[, options])
追加: v22.3.0, v20.18.0
options
<Object> モックモジュールのオプション設定。以下のプロパティがサポートされています。cache
<boolean>false
の場合、require()
またはimport()
を呼び出すたびに新しいモックモジュールが生成されます。true
の場合、後続の呼び出しでは同じモックモジュールが返され、モックモジュールは CommonJS キャッシュに挿入されます。デフォルト: false。defaultExport
<any> モックモジュールのデフォルトエクスポートとして使用されるオプションの値。この値が提供されない場合、ESM モックにはデフォルトエクスポートが含まれません。モックが CommonJS モジュールまたはビルトインモジュールの場合は、この設定がmodule.exports
の値として使用されます。この値が提供されない場合、CJS とビルトインモックはmodule.exports
の値として空のオブジェクトを使用します。namedExports
<Object> キーと値を使用してモックモジュールの名前付きエクスポートを作成するオプションのオブジェクト。モックが CommonJS モジュールまたはビルトインモジュールの場合は、これらの値がmodule.exports
にコピーされます。したがって、名前付きエクスポートとオブジェクト以外のデフォルトエクスポートの両方を使用してモックが作成された場合、CJS またはビルトインモジュールとして使用されると、モックは例外をスローします。
戻り値: <MockModuleContext> モックを操作するために使用できるオブジェクト。
この関数は、ECMAScript モジュール、CommonJS モジュール、および Node.js ビルトインモジュールのエクスポートをモックするために使用されます。モックする前に元のモジュールへの参照は影響を受けません。モジュールモックを有効にするには、--experimental-test-module-mocks
コマンドラインフラグを使用して Node.js を起動する必要があります。
次の例は、モックがどのようにモジュールに対して作成されるかを示しています。
test('mocks a builtin module in both module systems', async t => {
// 'node:readline' のモックを、名前付きエクスポート 'fn' を使用して作成します。
// 'fn' は元の '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() は元の 'node:readline' モジュールのエクスポートです。
assert.strictEqual(esmImpl.cursorTo, undefined)
assert.strictEqual(cjsImpl.cursorTo, undefined)
assert.strictEqual(esmImpl.fn(), 42)
assert.strictEqual(cjsImpl.fn(), 42)
mock.restore()
// モックが復元され、元のビルトインモジュールが返されます。
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()
追加バージョン: v19.1.0, v18.13.0
この関数は、このMockTracker
によって以前に作成されたすべてのモックのデフォルトの動作を復元し、モックとMockTracker
インスタンスの関連付けを解除します。関連付けが解除された後もモックは使用できますが、MockTracker
インスタンスを使用してそれらの動作をリセットしたり、それらとやり取りしたりすることはできなくなります。
各テストの完了後、この関数はテストコンテキストのMockTracker
で呼び出されます。グローバルMockTracker
を広く使用している場合は、この関数を手動で呼び出すことをお勧めします。
mock.restoreAll()
追加バージョン: v19.1.0, v18.13.0
この関数は、このMockTracker
によって以前に作成されたすべてのモックのデフォルトの動作を復元します。mock.reset()
とは異なり、mock.restoreAll()
はモックとMockTracker
インスタンスの関連付けを解除しません。
mock.setter(object, methodName[, implementation][, options])
追加バージョン: v19.3.0, v18.13.0
この関数は、options.setter
をtrue
に設定したMockTracker.method
のシンタックスシュガーです。
クラス: MockTimers
[履歴]
バージョン | 変更 |
---|---|
v23.1.0 | Mock Timers が安定版になりました。 |
v20.4.0, v18.19.0 | 追加バージョン: v20.4.0, v18.19.0 |
タイマーのモック化は、ソフトウェアテストで一般的に使用される手法であり、setInterval
やsetTimeout
などのタイマーの動作を、指定された時間間隔を実際に待たずにシミュレートして制御します。
MockTimers はDate
オブジェクトのモック化も可能です。
MockTracker
は、MockTimers
インスタンスであるトップレベルのtimers
エクスポートを提供します。
timers.enable([enableOptions])
[履歴]
バージョン | 変更 |
---|---|
v21.2.0, v20.11.0 | 利用可能な API とデフォルトの初期エポックを含むオプションオブジェクトにパラメーターが更新されました。 |
v20.4.0, v18.19.0 | 追加バージョン: v20.4.0, v18.19.0 |
指定されたタイマーに対してタイマーモックを有効にします。
enableOptions
<オブジェクト> タイマーモックを有効にするためのオプションの構成オプション。次のプロパティがサポートされています。apis
<配列> モックするタイマーを含むオプションの配列。現在サポートされているタイマーの値は'setInterval'
、'setTimeout'
、'setImmediate'
、'Date'
です。デフォルト:['setInterval', 'setTimeout', 'setImmediate', 'Date']
。配列が提供されない場合、時間関連のすべての API('setInterval'
、'clearInterval'
、'setTimeout'
、'clearTimeout'
、'setImmediate'
、'clearImmediate'
、'Date'
)がデフォルトでモックされます。now
<数値> | <Date>Date.now()
の値として使用する初期時間(ミリ秒単位)を表すオプションの数値または Date オブジェクト。デフォルト:0
。
注意: 特定のタイマーのモックを有効にすると、関連付けられたクリア関数も暗黙的にモックされます。
注意: Date
をモックすると、同じ内部クロックを使用するため、モックされたタイマーの動作に影響します。
初期時間を設定しない場合の使用例:
import { mock } from 'node:test'
mock.timers.enable({ apis: ['setInterval'] })
const { mock } = require('node:test')
mock.timers.enable({ apis: ['setInterval'] })
上記の例では、setInterval
タイマーのモックを有効にし、clearInterval
関数を暗黙的にモックします。node:timers、node:timers/promises、およびglobalThis
のsetInterval
およびclearInterval
関数のみがモックされます。
初期時間を設定した場合の使用例:
import { mock } from 'node:test'
mock.timers.enable({ apis: ['Date'], now: 1000 })
const { mock } = require('node:test')
mock.timers.enable({ apis: ['Date'], now: 1000 })
初期 Date オブジェクトを時間として設定した場合の使用例:
import { mock } from 'node:test'
mock.timers.enable({ apis: ['Date'], now: new Date() })
const { mock } = require('node:test')
mock.timers.enable({ apis: ['Date'], now: new Date() })
あるいは、パラメーターなしでmock.timers.enable()
を呼び出すと:
すべてのタイマー('setInterval'
、'clearInterval'
、'setTimeout'
、'clearTimeout'
、'setImmediate'
、'clearImmediate'
)がモックされます。node:timers
、node:timers/promises
、およびglobalThis
のsetInterval
、clearInterval
、setTimeout
、clearTimeout
、setImmediate
、およびclearImmediate
関数がモックされます。グローバルDate
オブジェクトも同様にモックされます。
timers.reset()
追加: v20.4.0, v18.19.0
この関数は、このMockTimers
インスタンスによって以前に作成されたすべてのモックのデフォルトの動作を復元し、MockTracker
インスタンスからモックを関連付け解除します。
注記: 各テストの完了後、この関数はテストコンテキストのMockTracker
で呼び出されます。
import { mock } from 'node:test'
mock.timers.reset()
const { mock } = require('node:test')
mock.timers.reset()
timers[Symbol.dispose]()
timers.reset()
を呼び出します。
timers.tick([milliseconds])
追加: v20.4.0, v18.19.0
すべてのモックされたタイマーに対して時間を進めます。
milliseconds
<number> タイマーを進める時間(ミリ秒単位)。デフォルト:1
。
注記: これは Node.js のsetTimeout
の動作とは異なり、正の数のみを受け入れます。Node.js では、負の数のsetTimeout
は Web との互換性のためにのみサポートされています。
次の例では、setTimeout
関数をモックし、.tick
を使用して時間を進めて、保留中のすべてのタイマーをトリガーします。
import assert from 'node:assert'
import { test } from 'node:test'
test('mocks setTimeout to be executed synchronously without having to actually wait for it', context => {
const fn = context.mock.fn()
context.mock.timers.enable({ apis: ['setTimeout'] })
setTimeout(fn, 9999)
assert.strictEqual(fn.mock.callCount(), 0)
// 時間を進める
context.mock.timers.tick(9999)
assert.strictEqual(fn.mock.callCount(), 1)
})
const assert = require('node:assert')
const { test } = require('node:test')
test('mocks setTimeout to be executed synchronously without having to actually wait for it', context => {
const fn = context.mock.fn()
context.mock.timers.enable({ apis: ['setTimeout'] })
setTimeout(fn, 9999)
assert.strictEqual(fn.mock.callCount(), 0)
// 時間を進める
context.mock.timers.tick(9999)
assert.strictEqual(fn.mock.callCount(), 1)
})
あるいは、.tick
関数を複数回呼び出すこともできます。
import assert from 'node:assert'
import { test } from 'node:test'
test('mocks setTimeout to be executed synchronously without having to actually wait for it', 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)
})
const assert = require('node:assert')
const { test } = require('node:test')
test('mocks setTimeout to be executed synchronously without having to actually wait for it', 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)
})
.tick
を使用して時間を進めると、モックが有効になってから作成されたDate
オブジェクトの時間も進みます(Date
もモックするように設定されている場合)。
import assert from 'node:assert'
import { test } from 'node:test'
test('mocks setTimeout to be executed synchronously without having to actually wait for it', 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)
// 時間を進める
context.mock.timers.tick(9999)
assert.strictEqual(fn.mock.callCount(), 1)
assert.strictEqual(Date.now(), 9999)
})
const assert = require('node:assert')
const { test } = require('node:test')
test('mocks setTimeout to be executed synchronously without having to actually wait for it', 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)
// 時間を進める
context.mock.timers.tick(9999)
assert.strictEqual(fn.mock.callCount(), 1)
assert.strictEqual(Date.now(), 9999)
})
明確な関数の使用
前述のように、タイマーのすべてのクリア関数(clearTimeout
、clearInterval
、clearImmediate
)は暗黙的にモックされます。setTimeout
を使用した次の例を見てください。
import assert from 'node:assert'
import { test } from 'node:test'
test('mocks setTimeout to be executed synchronously without having to actually wait for it', context => {
const fn = context.mock.fn()
// Optionally choose what to mock
context.mock.timers.enable({ apis: ['setTimeout'] })
const id = setTimeout(fn, 9999)
// 暗黙的にモックされる
clearTimeout(id)
context.mock.timers.tick(9999)
// setTimeoutがクリアされたため、モック関数は呼び出されない
assert.strictEqual(fn.mock.callCount(), 0)
})
const assert = require('node:assert')
const { test } = require('node:test')
test('mocks setTimeout to be executed synchronously without having to actually wait for it', context => {
const fn = context.mock.fn()
// Optionally choose what to mock
context.mock.timers.enable({ apis: ['setTimeout'] })
const id = setTimeout(fn, 9999)
// 暗黙的にモックされる
clearTimeout(id)
context.mock.timers.tick(9999)
// setTimeoutがクリアされたため、モック関数は呼び出されない
assert.strictEqual(fn.mock.callCount(), 0)
})
Node.js タイマーモジュールの使用
タイマーのモックを有効にすると、node:timers、node:timers/promisesモジュール、および Node.js グローバルコンテキストからのタイマーが有効になります。
注記: import { setTimeout } from 'node:timers'
のようなデストラクチャリング関数は、現在この API ではサポートされていません。
import assert from 'node:assert'
import { test } from 'node:test'
import nodeTimers from 'node:timers'
import nodeTimersPromises from 'node:timers/promises'
test('mocks setTimeout to be executed synchronously without having to actually wait for it', async context => {
const globalTimeoutObjectSpy = context.mock.fn()
const nodeTimerSpy = context.mock.fn()
const nodeTimerPromiseSpy = context.mock.fn()
// Optionally choose what to mock
context.mock.timers.enable({ apis: ['setTimeout'] })
setTimeout(globalTimeoutObjectSpy, 9999)
nodeTimers.setTimeout(nodeTimerSpy, 9999)
const promise = nodeTimersPromises.setTimeout(9999).then(nodeTimerPromiseSpy)
// 時間を進める
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)
})
const assert = require('node:assert')
const { test } = require('node:test')
const nodeTimers = require('node:timers')
const nodeTimersPromises = require('node:timers/promises')
test('mocks setTimeout to be executed synchronously without having to actually wait for it', async context => {
const globalTimeoutObjectSpy = context.mock.fn()
const nodeTimerSpy = context.mock.fn()
const nodeTimerPromiseSpy = context.mock.fn()
// Optionally choose what to mock
context.mock.timers.enable({ apis: ['setTimeout'] })
setTimeout(globalTimeoutObjectSpy, 9999)
nodeTimers.setTimeout(nodeTimerSpy, 9999)
const promise = nodeTimersPromises.setTimeout(9999).then(nodeTimerPromiseSpy)
// 時間を進める
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)
})
Node.js では、node:timers/promisesのsetInterval
はAsyncGenerator
であり、この API でもサポートされています。
import assert from 'node:assert'
import { test } from 'node:test'
import nodeTimersPromises from 'node:timers/promises'
test('should tick five times testing a real use case', 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)
}
})
const assert = require('node:assert')
const { test } = require('node:test')
const nodeTimersPromises = require('node:timers/promises')
test('should tick five times testing a real use case', 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()
追加: v20.4.0, v18.19.0
保留中の全てのモックタイマーを即座にトリガーします。Date
オブジェクトもモックされている場合、Date
オブジェクトを最も遠いタイマーの時間に進めます。
以下の例では、保留中の全てのタイマーを即座にトリガーし、遅延なく実行します。
import assert from 'node:assert'
import { test } from 'node:test'
test('runAll functions following the given order', context => {
context.mock.timers.enable({ apis: ['setTimeout', 'Date'] })
const results = []
setTimeout(() => results.push(1), 9999)
// Notice that if both timers have the same timeout,
// the order of execution is guaranteed
setTimeout(() => results.push(3), 8888)
setTimeout(() => results.push(2), 8888)
assert.deepStrictEqual(results, [])
context.mock.timers.runAll()
assert.deepStrictEqual(results, [3, 2, 1])
// The Date object is also advanced to the furthest timer's time
assert.strictEqual(Date.now(), 9999)
})
const assert = require('node:assert')
const { test } = require('node:test')
test('runAll functions following the given order', context => {
context.mock.timers.enable({ apis: ['setTimeout', 'Date'] })
const results = []
setTimeout(() => results.push(1), 9999)
// Notice that if both timers have the same timeout,
// the order of execution is guaranteed
setTimeout(() => results.push(3), 8888)
setTimeout(() => results.push(2), 8888)
assert.deepStrictEqual(results, [])
context.mock.timers.runAll()
assert.deepStrictEqual(results, [3, 2, 1])
// The Date object is also advanced to the furthest timer's time
assert.strictEqual(Date.now(), 9999)
})
注記: runAll()
関数は、タイマーモックのコンテキストでタイマーをトリガーするために特別に設計されています。モック環境外のリアルタイムシステムクロックや実際のタイマーには影響しません。
timers.setTime(milliseconds)
追加: v21.2.0, v20.11.0
モックされたDate
オブジェクトの参照として使用される現在の Unix タイムスタンプを設定します。
import assert from 'node:assert'
import { test } from 'node:test'
test('runAll functions following the given order', context => {
const now = Date.now()
const setTime = 1000
// Date.now is not mocked
assert.deepStrictEqual(Date.now(), now)
context.mock.timers.enable({ apis: ['Date'] })
context.mock.timers.setTime(setTime)
// Date.now is now 1000
assert.strictEqual(Date.now(), setTime)
})
const assert = require('node:assert')
const { test } = require('node:test')
test('setTime replaces current time', context => {
const now = Date.now()
const setTime = 1000
// Date.now is not mocked
assert.deepStrictEqual(Date.now(), now)
context.mock.timers.enable({ apis: ['Date'] })
context.mock.timers.setTime(setTime)
// Date.now is now 1000
assert.strictEqual(Date.now(), setTime)
})
日付とタイマーの連携
日付オブジェクトとタイマーオブジェクトは互いに依存しています。setTime()
を使用してモックされた Date
オブジェクトに現在時刻を渡した場合、setTimeout
と setInterval
で設定されたタイマーは影響を受けません。
しかし、tick
メソッドはモックされた Date
オブジェクトを進めます。
import assert from 'node:assert'
import { test } from 'node:test'
test('runAll関数は指定された順序に従って実行される', 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, [])
// 日付は進みますが、タイマーは動作しません
assert.strictEqual(Date.now(), 12000)
})
const assert = require('node:assert')
const { test } = require('node:test')
test('runAll関数は指定された順序に従って実行される', 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, [])
// 日付は進みますが、タイマーは動作しません
assert.strictEqual(Date.now(), 12000)
})
クラス: TestsStream
[履歴]
バージョン | 変更内容 |
---|---|
v20.0.0, v19.9.0, v18.17.0 | テストがスイートの場合の test:pass および test:fail イベントに型を追加 |
v18.9.0, v16.19.0 | 追加日: v18.9.0, v16.19.0 |
- <Readable> を継承
run()
メソッドへの呼び出しが成功すると、新しい<TestsStream>オブジェクトが返され、テストの実行を表す一連のイベントがストリームされます。TestsStream
は、テストの定義順にイベントを発行します。
一部のイベントは、テストが定義されたのと同じ順序で発行されることが保証されていますが、他のイベントはテストが実行された順序で発行されます。
イベント: 'test:coverage'
data
<Object>summary
<Object> カバレッジレポートを含むオブジェクト。files
<Array> 個々のファイルのコードカバレッジレポートの配列。各レポートは次のスキーマを持つオブジェクトです。path
<string> ファイルの絶対パス。totalLineCount
<number> 行の総数。totalBranchCount
<number> ブランチの総数。totalFunctionCount
<number> 関数の総数。coveredLineCount
<number> カバレッジのある行数。coveredBranchCount
<number> カバレッジのあるブランチ数。coveredFunctionCount
<number> カバレッジのある関数数。coveredLinePercent
<number> 行カバレッジの割合。coveredBranchPercent
<number> ブランチカバレッジの割合。coveredFunctionPercent
<number> 関数カバレッジの割合。functions
<Array> 関数カバレッジを表す関数の配列。name
<string> 関数の名前。line
<number> 関数が定義されている行番号。count
<number> 関数が呼び出された回数。branches
<Array> ブランチカバレッジを表すブランチの配列。line
<number> ブランチが定義されている行番号。count
<number> ブランチが実行された回数。lines
<Array> 行番号とカバレッジ回数を表す行の配列。line
<number> 行番号。count
<number> 行がカバレッジされた回数。thresholds
<Object> 各カバレッジの種類に対するカバレッジの可否を含むオブジェクト。function
<number> 関数カバレッジの閾値。branch
<number> ブランチカバレッジの閾値。line
<number> 行カバレッジの閾値。totals
<Object> すべてのファイルのカバレッジのサマリーを含むオブジェクト。totalLineCount
<number> 行の総数。totalBranchCount
<number> ブランチの総数。totalFunctionCount
<number> 関数の総数。coveredLineCount
<number> カバレッジのある行数。coveredBranchCount
<number> カバレッジのあるブランチ数。coveredFunctionCount
<number> カバレッジのある関数数。coveredLinePercent
<number> 行カバレッジの割合。coveredBranchPercent
<number> ブランチカバレッジの割合。coveredFunctionPercent
<number> 関数カバレッジの割合。workingDirectory
<string> コードカバレッジが開始された時の作業ディレクトリ。テストによって Node.js プロセスの作業ディレクトリが変更された場合に、相対パス名を表示するのに役立ちます。nesting
<number> テストのネストレベル。
コードカバレッジが有効になり、すべてのテストが完了したときに送出されます。
イベント: 'test:complete'
data
<Object>column
<number> | <undefined> テストが定義されている列番号、または REPL でテストが実行された場合はundefined
。details
<Object> 追加の実行メタデータ。passed
<boolean> テストがパスしたかどうか。duration_ms
<number> テストのミリ秒単位の期間。error
<Error> | <undefined> テストがパスしなかった場合、テストによってスローされたエラーをラップするエラー。cause
<Error> テストによって実際にスローされたエラー。type
<string> | <undefined> テストの種類。これがスイートかどうかを示すために使用されます。file
<string> | <undefined> テストファイルのパス。テストが REPL で実行された場合はundefined
。line
<number> | <undefined> テストが定義されている行番号、または REPL でテストが実行された場合はundefined
。name
<string> テスト名。nesting
<number> テストのネストレベル。testNumber
<number> テストの序数。todo
<string> | <boolean> | <undefined>context.todo
が呼び出された場合に存在します。skip
<string> | <boolean> | <undefined>context.skip
が呼び出された場合に存在します。
テストの実行が完了すると発生します。このイベントは、テストが定義された順序と同じ順序で発生するとは限りません。対応する宣言順序イベントは'test:pass'
と'test:fail'
です。
イベント: 'test:dequeue'
data
<Object>column
<number> | <undefined> テストが定義されている列番号、または REPL でテストが実行された場合はundefined
。file
<string> | <undefined> テストファイルのパス、REPL でテストが実行された場合はundefined
。line
<number> | <undefined> テストが定義されている行番号、または REPL でテストが実行された場合はundefined
。name
<string> テスト名。nesting
<number> テストのネストレベル。
テストが実行される直前に、キューからテストが取り出されたときに発生します。このイベントは、テストが定義された順序と同じ順序で発生するとは限りません。対応する宣言順序イベントは'test:start'
です。
イベント: 'test:diagnostic'
data
<Object>column
<number> | <undefined> テストが定義されている列番号、または REPL でテストが実行された場合はundefined
。file
<string> | <undefined> テストファイルのパス、REPL でテストが実行された場合はundefined
。line
<number> | <undefined> テストが定義されている行番号、または REPL でテストが実行された場合はundefined
。message
<string> 診断メッセージ。nesting
<number> テストのネストレベル。
context.diagnostic
が呼び出されたときに発生します。このイベントは、テストが定義された順序と同じ順序で発生することが保証されています。
Event: 'test:enqueue'
data
<Object>column
<number> | <undefined> テストが定義されている列番号、または REPL でテストが実行された場合はundefined
。file
<string> | <undefined> テストファイルのパス、テストが REPL で実行された場合はundefined
。line
<number> | <undefined> テストが定義されている行番号、または REPL でテストが実行された場合はundefined
。name
<string> テスト名。nesting
<number> テストのネストレベル。
テストが実行のためにキューに追加されたときに送出されます。
Event: 'test:fail'
data
<Object>column
<number> | <undefined> テストが定義されている列番号、または REPL でテストが実行された場合はundefined
。details
<Object> 追加の実行メタデータ。duration_ms
<number> テストのミリ秒単位の期間。error
<Error> テストによってスローされたエラーをラップするエラー。cause
<Error> テストによって実際にスローされたエラー。type
<string> | <undefined> テストの種類。これはスイートであるかどうかを示すために使用されます。file
<string> | <undefined> テストファイルのパス、テストが REPL で実行された場合はundefined
。line
<number> | <undefined> テストが定義されている行番号、または REPL でテストが実行された場合はundefined
。name
<string> テスト名。nesting
<number> テストのネストレベル。testNumber
<number> テストの序数。todo
<string> | <boolean> | <undefined>context.todo
が呼び出された場合に存在します。skip
<string> | <boolean> | <undefined>context.skip
が呼び出された場合に存在します。
テストが失敗したときに送出されます。このイベントは、テストが定義されているのと同じ順序で送出されることが保証されています。対応する実行順序イベントは'test:complete'
です。
イベント: 'test:pass'
data
<Object>column
<number> | <undefined> テストが定義されている列番号、または REPL でテストが実行された場合はundefined
。details
<Object> 追加の実行メタデータ。duration_ms
<number> テストの実行時間(ミリ秒)。type
<string> | <undefined> テストの種類。これはスイートであるかどうかを示すために使用されます。file
<string> | <undefined> テストファイルのパス。テストが REPL で実行された場合はundefined
。line
<number> | <undefined> テストが定義されている行番号、または REPL でテストが実行された場合はundefined
。name
<string> テスト名。nesting
<number> テストのネストレベル。testNumber
<number> テストの序数。todo
<string> | <boolean> | <undefined>context.todo
が呼び出された場合に存在します。skip
<string> | <boolean> | <undefined>context.skip
が呼び出された場合に存在します。
テストがパスした場合に送出されます。このイベントは、テストが定義された順序と同じ順序で送出されることが保証されています。対応する実行順序イベントは'test:complete'
です。
イベント: 'test:plan'
data
<Object>column
<number> | <undefined> テストが定義されている列番号、または REPL でテストが実行された場合はundefined
。file
<string> | <undefined> テストファイルのパス、REPL でテストが実行された場合はundefined
。line
<number> | <undefined> テストが定義されている行番号、または REPL でテストが実行された場合はundefined
。nesting
<number> テストのネストレベル。count
<number> 実行されたサブテストの数。
与えられたテストについて、すべてのサブテストが完了したときに発生します。このイベントは、テストが定義されたのと同じ順序で発生することが保証されています。
イベント: 'test:start'
data
<Object>column
<number> | <undefined> テストが定義されている列番号、または REPL でテストが実行された場合はundefined
。file
<string> | <undefined> テストファイルのパス、REPL でテストが実行された場合はundefined
。line
<number> | <undefined> テストが定義されている行番号、または REPL でテストが実行された場合はundefined
。name
<string> テスト名。nesting
<number> テストのネストレベル。
テストが自身の状態とサブテストの状態を報告し始めるときに発生します。このイベントは、テストが定義されたのと同じ順序で発生することが保証されています。対応する実行順序イベントは'test:dequeue'
です。
イベント: 'test:stderr'
実行中のテストがstderr
に出力した際に発行されます。このイベントは--test
フラグが渡された場合にのみ発行されます。このイベントは、テストが定義された順序で発行されるとは限りません。
イベント: 'test:stdout'
実行中のテストがstdout
に出力した際に発行されます。このイベントは--test
フラグが渡された場合にのみ発行されます。このイベントは、テストが定義された順序で発行されるとは限りません。
イベント: 'test:summary'
data
<Object>counts
<Object> さまざまなテスト結果の数を格納したオブジェクト。cancelled
<number> キャンセルされたテストの総数。failed
<number> 失敗したテストの総数。passed
<number> 成功したテストの総数。skipped
<number> スキップされたテストの総数。suites
<number> 実行されたスイートの総数。tests
<number> スイートを除く、実行されたテストの総数。todo
<number> TODO テストの総数。topLevel
<number> トップレベルのテストとスイートの総数。duration_ms
<number> テスト実行時間(ミリ秒)。file
<string> | <undefined> サマリーを生成したテストファイルのパス。サマリーが複数のファイルに対応する場合はundefined
。success
<boolean> テスト実行が成功したかどうかを示します。失敗したテストや満たされていないカバレッジしきい値など、エラー状態が発生した場合はfalse
に設定されます。
テスト実行が完了したときに発行されます。このイベントには、完了したテスト実行に関するメトリクスが含まれており、テスト実行が成功したか失敗したかを判断するのに役立ちます。プロセスレベルのテスト分離を使用する場合、最終的な累積サマリーに加えて、各テストファイルごとに'test:summary'
イベントが生成されます。
イベント: 'test:watch:drained'
ウォッチモードで実行待ちのテストがなくなったときに送出されます。
クラス: TestContext
[履歴]
バージョン | 変更点 |
---|---|
v20.1.0, v18.17.0 | before 関数がTestContext に追加されました。 |
v18.0.0, v16.17.0 | 追加: v18.0.0, v16.17.0 |
TestContext
のインスタンスは、テストランナーとやり取りするために各テスト関数に渡されます。ただし、TestContext
コンストラクタは API の一部として公開されていません。
context.before([fn][, options])
追加: v20.1.0, v18.17.0
fn
<Function> | <AsyncFunction> フック関数。この関数の最初の引数はTestContext
オブジェクトです。フックがコールバックを使用する場合、コールバック関数は 2 番目の引数として渡されます。デフォルト: 何もしない関数。options
<Object> フックの構成オプション。以下のプロパティがサポートされています:signal
<AbortSignal> 進行中のフックの中断を許可します。timeout
<number> フックが失敗するまでのミリ秒数。指定しない場合、サブテストは親からこの値を継承します。デフォルト:Infinity
。
この関数は、現在のテストのサブテストの前に実行されるフックを作成するために使用されます。
context.beforeEach([fn][, options])
追加: v18.8.0, v16.18.0
fn
<Function> | <AsyncFunction> フック関数。この関数の最初の引数はTestContext
オブジェクトです。フックがコールバックを使用する場合、コールバック関数は 2 番目の引数として渡されます。デフォルト: 何もしない関数。options
<Object> フックの構成オプション。以下のプロパティがサポートされています:signal
<AbortSignal> 進行中のフックの中断を許可します。timeout
<number> フックが失敗するまでのミリ秒数。指定しない場合、サブテストは親からこの値を継承します。デフォルト:Infinity
。
この関数は、現在のテストの各サブテストの前に実行されるフックを作成するために使用されます。
test('トップレベルテスト', async t => {
t.beforeEach(t => t.diagnostic(`about to run ${t.name}`))
await t.test('これはサブテストです', t => {
assert.ok('some relevant assertion here')
})
})
context.after([fn][, options])
追加: v19.3.0, v18.13.0
fn
<Function> | <AsyncFunction> フック関数。この関数の最初の引数はTestContext
オブジェクトです。フックがコールバックを使用する場合、コールバック関数が 2 番目の引数として渡されます。デフォルト: 何もしない関数。options
<Object> フックの構成オプション。以下のプロパティがサポートされています。signal
<AbortSignal> 実行中のフックの中断を許可します。timeout
<number> フックが失敗するまでのミリ秒数。指定しない場合、サブテストは親からこの値を継承します。デフォルト:Infinity
。
この関数は、現在のテストが終了した後に実行されるフックを作成するために使用されます。
test('top level test', async t => {
t.after(t => t.diagnostic(`finished running ${t.name}`))
assert.ok('some relevant assertion here')
})
context.afterEach([fn][, options])
追加: v18.8.0, v16.18.0
fn
<Function> | <AsyncFunction> フック関数。この関数の最初の引数はTestContext
オブジェクトです。フックがコールバックを使用する場合、コールバック関数が 2 番目の引数として渡されます。デフォルト: 何もしない関数。options
<Object> フックの構成オプション。以下のプロパティがサポートされています。signal
<AbortSignal> 実行中のフックの中断を許可します。timeout
<number> フックが失敗するまでのミリ秒数。指定しない場合、サブテストは親からこの値を継承します。デフォルト:Infinity
。
この関数は、現在のテストの各サブテストの後で実行されるフックを作成するために使用されます。
test('top level test', async t => {
t.afterEach(t => t.diagnostic(`finished running ${t.name}`))
await t.test('This is a subtest', t => {
assert.ok('some relevant assertion here')
})
})
context.assert
追加日: v22.2.0, v20.15.0
context
にバインドされたアサーションメソッドを含むオブジェクト。node:assert
モジュールのトップレベル関数は、テストプランを作成するためにここで公開されています。
test('test', t => {
t.plan(1)
t.assert.strictEqual(true, true)
})
context.assert.snapshot(value[, options])
追加日: v22.3.0
value
<any> 文字列にシリアル化する値。Node.js が--test-update-snapshots
フラグで起動された場合、シリアル化された値はスナップショットファイルに書き込まれます。それ以外の場合は、シリアル化された値は既存のスナップショットファイル内の対応する値と比較されます。options
<Object> オプションの構成オプション。次のプロパティがサポートされています。serializers
<Array>value
を文字列にシリアル化するのに使用される同期関数の配列。value
は最初のシリアライザ関数への唯一の引数として渡されます。各シリアライザの戻り値は、次のシリアライザへの入力として渡されます。すべてのシリアライザが実行されると、結果の値は文字列に変換されます。デフォルト: シリアライザが提供されない場合、テストランナーのデフォルトのシリアライザが使用されます。
この関数は、スナップショットテストのアサーションを実装します。
test('snapshot test with default serialization', t => {
t.assert.snapshot({ value1: 1, value2: 2 })
})
test('snapshot test with custom serialization', t => {
t.assert.snapshot(
{ value3: 3, value4: 4 },
{
serializers: [value => JSON.stringify(value)],
}
)
})
context.diagnostic(message)
追加されたバージョン: v18.0.0, v16.17.0
message
<string> 報告するメッセージ。
この関数は、診断情報を出力に書き込むために使用されます。診断情報は、テスト結果の最後に含まれます。この関数は値を返しません。
test('トップレベルテスト', t => {
t.diagnostic('診断メッセージ')
})
context.filePath
追加されたバージョン: v22.6.0, v20.16.0
現在のテストを作成したテストファイルの絶対パス。テストファイルがテストを生成する追加のモジュールをインポートする場合、インポートされたテストはルートテストファイルのパスを返します。
context.fullName
追加されたバージョン: v22.3.0
テストとその祖先の名前を>
で区切ったもの。
context.name
追加されたバージョン: v18.8.0, v16.18.0
テストの名前。
context.plan(count)
[履歴]
バージョン | 変更 |
---|---|
v23.4.0 | この関数は実験的ではなくなりました。 |
v22.2.0, v20.15.0 | 追加されたバージョン: v22.2.0, v20.15.0 |
count
<number> 実行されるアサーションとサブテストの予想数。
この関数は、テスト内で実行されるアサーションとサブテストの数を設定するために使用されます。実行されるアサーションとサブテストの数が予想数と一致しない場合、テストは失敗します。
test('トップレベルテスト', t => {
t.plan(2)
t.assert.ok('some relevant assertion here')
t.test('サブテスト', () => {})
})
非同期コードを使用する場合、plan
関数は、正しい数の assertion が実行されることを保証するために使用できます。
test('ストリームを使った計画', (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)
追加: v18.0.0, v16.17.0
shouldRunOnlyTests
<boolean>only
オプション付きのテストを実行するかどうか。
shouldRunOnlyTests
が真の場合、テストコンテキストは only
オプションが設定されているテストのみを実行します。それ以外の場合は、すべてのテストが実行されます。Node.js が --test-only
コマンドラインオプションで起動されていない場合、この関数は何もしません。
test('トップレベルテスト', t => {
// テストコンテキストは、'only' オプションを使用してサブテストを実行するように設定できます。
t.runOnly(true)
return Promise.all([
t.test('このサブテストはスキップされます'),
t.test('このサブテストは実行されます', { only: true }),
])
})
context.signal
追加: v18.7.0, v16.17.0
テストが中断されたときに、テストのサブタスクの中断に使用できます。
test('トップレベルテスト', async t => {
await fetch('some/uri', { signal: t.signal })
})
context.skip([message])
追加: v18.0.0, v16.17.0
message
<string> オプションのスキップメッセージ。
この関数は、テストの出力をスキップされたテストとして示します。message
が指定されている場合、出力に含まれます。skip()
を呼び出しても、テスト関数の実行は終了しません。この関数は値を返しません。
test('トップレベルテスト', t => {
// テストに追加のロジックが含まれている場合も、ここで返すようにしてください。
t.skip('これはスキップされます')
})
context.todo([message])
追加: v18.0.0, v16.17.0
message
<string> オプションのTODO
メッセージ。
この関数は、テストの出力に TODO
ディレクティブを追加します。message
が指定されている場合、出力に含まれます。todo()
を呼び出しても、テスト関数の実行は終了しません。この関数は値を返しません。
test('トップレベルテスト', t => {
// このテストは `TODO` としてマークされています
t.todo('これはTODOです')
})
context.test([name][, options][, fn])
[履歴]
バージョン | 変更内容 |
---|---|
v18.8.0, v16.18.0 | signal オプションを追加 |
v18.7.0, v16.17.0 | timeout オプションを追加 |
v18.0.0, v16.17.0 | 追加: v18.0.0, v16.17.0 |
name
<string> サブテストの名前。テスト結果のレポートに表示されます。デフォルト:fn
のname
プロパティ、またはfn
に名前がない場合は'<anonymous>'
。options
<Object> サブテストの構成オプション。以下のプロパティがサポートされています。concurrency
<number> | <boolean> | <null> 数値を指定すると、その数のテストがアプリケーションスレッド内で並列に実行されます。true
の場合、すべてのサブテストが並列に実行されます。false
の場合、一度に 1 つのテストしか実行されません。指定しない場合、サブテストは親からこの値を継承します。デフォルト:null
。only
<boolean> 真理値の場合、テストコンテキストがonly
テストを実行するように構成されていると、このテストが実行されます。それ以外の場合は、テストはスキップされます。デフォルト:false
。signal
<AbortSignal> 実行中のテストの中断を許可します。skip
<boolean> | <string> 真理値の場合、テストはスキップされます。文字列を指定すると、その文字列がテスト結果にテストスキップの理由として表示されます。デフォルト:false
。todo
<boolean> | <string> 真理値の場合、テストはTODO
としてマークされます。文字列を指定すると、その文字列がテスト結果にテストがTODO
である理由として表示されます。デフォルト:false
。timeout
<number> テストが失敗するまでのミリ秒数。指定しない場合、サブテストは親からこの値を継承します。デフォルト:Infinity
。plan
<number> テストで実行されるアサーションとサブテストの予想数。テストで実行されるアサーション数がプランで指定された数と一致しない場合、テストは失敗します。デフォルト:undefined
。
fn
<Function> | <AsyncFunction> テスト対象の関数。この関数の最初の引数はTestContext
オブジェクトです。テストがコールバックを使用する場合、コールバック関数は 2 番目の引数として渡されます。デフォルト: 何もしない関数。戻り値: <Promise> テストが完了すると
undefined
で解決されます。
この関数は、現在のテストの下にサブテストを作成するために使用されます。この関数は、最上位レベルのtest()
関数と同じように動作します。
test('トップレベルテスト', async t => {
await t.test('これはサブテストです', { only: false, skip: false, concurrency: 1, todo: false, plan: 1 }, t => {
t.assert.ok('ここに関連するアサーションがあります')
})
})
クラス: SuiteContext
追加: v18.7.0, v16.17.0
SuiteContext
のインスタンスは、テストランナーとやり取りするために各スイート関数に渡されます。ただし、SuiteContext
コンストラクタは API の一部として公開されていません。
context.filePath
追加: v22.6.0
現在のスイートを作成したテストファイルの絶対パス。テストファイルがスイートを生成する追加のモジュールをインポートする場合、インポートされたスイートはルートテストファイルのパスを返します。
context.name
追加: v18.8.0, v16.18.0
スイートの名前。
context.signal
追加: v18.7.0, v16.17.0
テストが中断されたときに、テストのサブタスクの中断に使用できます。