Node.js v21.7.2 ドキュメント
- Node.js v21.7.2
-
► 目次
- テストランナー
- サブテスト
- テストのスキップ
describe
/it
構文only
テスト- 名前によるテストのフィルタリング
- 外部非同期アクティビティ
- ウォッチモード
- コマンドラインからのテストの実行
- コードカバレッジの収集
- モッキング
- テストレポーター
run([options])
test([name][, options][, fn])
test.skip([name][, options][, fn])
test.todo([name][, options][, fn])
test.only([name][, options][, fn])
describe([name][, options][, fn])
describe.skip([name][, options][, fn])
describe.todo([name][, options][, fn])
describe.only([name][, options][, fn])
it([name][, options][, fn])
it.skip([name][, options][, fn])
it.todo([name][, options][, fn])
it.only([name][, options][, fn])
before([fn][, options])
after([fn][, options])
beforeEach([fn][, options])
afterEach([fn][, options])
- クラス:
MockFunctionContext
- クラス:
MockTracker
- クラス:
MockTimers
- クラス:
TestsStream
- クラス:
TestContext
context.before([fn][, options])
context.beforeEach([fn][, options])
context.after([fn][, options])
context.afterEach([fn][, options])
context.diagnostic(message)
context.name
context.runOnly(shouldRunOnlyTests)
context.signal
context.skip([message])
context.todo([message])
context.test([name][, options][, fn])
- クラス:
SuiteContext
- テストランナー
-
► インデックス
- アサーションテスト
- 非同期コンテキスト追跡
- 非同期フック
- バッファ
- C++ アドオン
- Node-API を使用した C/C++ アドオン
- C++ エンベッダー API
- 子プロセス
- クラスタ
- コマンドラインオプション
- コンソール
- Corepack
- 暗号
- デバッガ
- 非推奨 API
- 診断チャネル
- DNS
- ドメイン
- エラー
- イベント
- ファイルシステム
- グローバル
- HTTP
- HTTP/2
- HTTPS
- インスペクタ
- 国際化
- モジュール: CommonJS モジュール
- モジュール: ECMAScript モジュール
- モジュール:
node:module
API - モジュール: パッケージ
- Net
- OS
- パス
- パフォーマンスフック
- パーミッション
- プロセス
- Punycode
- クエリ文字列
- Readline
- REPL
- レポート
- 単一実行ファイルアプリケーション
- ストリーム
- 文字列デコーダー
- テストランナー
- タイマー
- TLS/SSL
- トレースイベント
- TTY
- UDP/データグラム
- URL
- ユーティリティ
- V8
- VM
- WASI
- Web Crypto API
- Web Streams API
- ワーカースレッド
- Zlib
- ► 他のバージョン
- ► オプション
テストランナー#
ソースコード: lib/test.js
node:test
モジュールは、JavaScript テストの作成を容易にします。アクセスするには
import test from 'node:test';
const test = require('node:test');
このモジュールは、node:
スキームでのみ使用できます。以下は動作しません
import test from 'test';
const test = require('test');
test
モジュールで作成されたテストは、3 つのいずれかの方法で処理される単一の関数で構成されます。
- 例外をスローした場合に失敗とみなされ、そうでない場合は成功とみなされる同期関数。
Promise
を返す関数。Promise
が拒否された場合に失敗とみなされ、Promise
が履行された場合に成功とみなされます。- コールバック関数を受け取る関数。コールバックが最初の引数として truthy 値を受け取った場合、テストは失敗とみなされます。コールバックの最初の引数として falsy 値が渡された場合、テストは成功とみなされます。テスト関数がコールバック関数を受け取り、かつ
Promise
を返す場合、テストは失敗します。
次の例は、test
モジュールを使用してテストを作成する方法を示しています。
test('synchronous passing test', (t) => {
// This test passes because it does not throw an exception.
assert.strictEqual(1, 1);
});
test('synchronous failing test', (t) => {
// This test fails because it throws an exception.
assert.strictEqual(1, 2);
});
test('asynchronous passing test', async (t) => {
// This test passes because the Promise returned by the async
// function is settled and not rejected.
assert.strictEqual(1, 1);
});
test('asynchronous failing test', async (t) => {
// This test fails because the Promise returned by the async
// function is rejected.
assert.strictEqual(1, 2);
});
test('failing test using Promises', (t) => {
// Promises can be used directly as well.
return new Promise((resolve, reject) => {
setImmediate(() => {
reject(new Error('this will cause the test to fail'));
});
});
});
test('callback passing test', (t, done) => {
// done() is the callback function. When the setImmediate() runs, it invokes
// done() with no arguments.
setImmediate(done);
});
test('callback failing test', (t, done) => {
// When the setImmediate() runs, done() is invoked with an Error object and
// the test fails.
setImmediate(() => {
done(new Error('callback failure'));
});
});
テストが失敗した場合、プロセス終了コードは 1
に設定されます。
サブテスト#
テストコンテキストの test()
メソッドを使用すると、サブテストを作成できます。より大きなテスト内にネストされたテストを作成できる、階層的な方法でテストを構成できます。このメソッドは、トップレベルの test()
関数と同様に動作します。次の例は、2 つのサブテストを含むトップレベルテストの作成を示しています。
test('top level test', async (t) => {
await t.test('subtest 1', (t) => {
assert.strictEqual(1, 1);
});
await t.test('subtest 2', (t) => {
assert.strictEqual(2, 2);
});
});
注:
beforeEach
およびafterEach
フックは、各サブテストの実行の間にトリガーされます。
この例では、await
を使用して両方のサブテストが完了したことを確認しています。これは、`describe` と `it` 構文で作成されたテストとは異なり、親テストはサブテストの完了を待機しないためです。親が終了したときに未処理のサブテストはキャンセルされ、失敗として扱われます。サブテストが失敗すると、親テストも失敗します。
テストのスキップ#
個々のテストは、テストに skip
オプションを渡すか、次の例に示すようにテストコンテキストの skip()
メソッドを呼び出すことでスキップできます。
// The skip option is used, but no message is provided.
test('skip option', { skip: true }, (t) => {
// This code is never executed.
});
// The skip option is used, and a message is provided.
test('skip option with message', { skip: 'this is skipped' }, (t) => {
// This code is never executed.
});
test('skip() method', (t) => {
// Make sure to return here as well if the test contains additional logic.
t.skip();
});
test('skip() method with message', (t) => {
// Make sure to return here as well if the test contains additional logic.
t.skip('this is skipped');
});
describe
/it
構文#
テストの実行は、スイートを宣言する describe
とテストを宣言する it
を使用しても実行できます。スイートは、関連するテストをまとめて整理およびグループ化するために使用されます。 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
オプションが設定されたテストが実行されると、すべてのサブテストも実行されます。テストコンテキストの runOnly()
メソッドを使用して、サブテストレベルで同じ動作を実装できます。
// Assume Node.js is run with the --test-only command-line option.
// The 'only' option is set, so this test is run.
test('this test is run', { only: true }, async (t) => {
// Within this test, all subtests are run by default.
await t.test('running subtest');
// The test context can be updated to run subtests with the 'only' option.
t.runOnly(true);
await t.test('this subtest is now skipped');
await t.test('this subtest is run', { only: true });
// Switch the context back to execute all tests.
t.runOnly(false);
await t.test('this subtest is now run');
// Explicitly do not run these tests.
await t.test('skipped subtest 3', { only: false });
await t.test('skipped subtest 4', { skip: true });
});
// The 'only' option is not set, so this test is skipped.
test('this test is not run', () => {
// This code is not run.
throw new Error('fail');
});
名前によるテストのフィルタリング#
--test-name-pattern
コマンドラインオプションを使用すると、名前が指定されたパターンと一致するテストのみを実行できます。テスト名パターンは、JavaScript 正規表現として解釈されます。ネストされたテストを実行するために、--test-name-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"
で Node.js を起動すると、パターンは大文字と小文字を区別しないため、Test 4
と Test 5
が一致します。
テスト名パターンは、テストランナーが実行するファイルのセットを変更しません。
外部非同期アクティビティ#
テスト関数が実行を完了すると、テストの順序を維持しながら、結果が可能な限り迅速に報告されます。ただし、テスト関数でテスト自体よりも長く存続する非同期アクティビティが生成される可能性があります。テストランナーはこの種のアクティビティを処理しますが、それを収容するためにテスト結果の報告を遅延させることはありません。
次の例では、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.
});
ウォッチモード#
Node.js テストランナーは、--watch
フラグを渡すことによって、ウォッチモードでの実行をサポートしています。
node --test --watch
ウォッチモードでは、テストランナーはテストファイルとその依存関係の変更を監視します。変更が検出されると、テストランナーは変更の影響を受けるテストを再実行します。テストランナーは、プロセスが終了するまで実行を続けます。
コマンドラインからのテストの実行#
Node.js テストランナーは、--test
フラグを渡すことでコマンドラインから起動できます。
node --test
デフォルトでは、Node.js はこれらのパターンに一致するすべてのファイルを実行します。
**/*.test.?(c|m)js
**/*-test.?(c|m)js
**/*_test.?(c|m)js
**/test-*.?(c|m)js
**/test.?(c|m)js
**/test/**/*.?(c|m)js
または、以下に示すように、Node.js コマンドの最後の引数として、1 つ以上の glob パターンを指定できます。glob パターンは、glob(7)
の動作に従います。
node --test **/*.test.js **/*.spec.js
一致するファイルは、テストファイルとして実行されます。テストファイルの実行に関する詳細は、テストランナー実行モデルセクションを参照してください。
テストランナー実行モデル#
一致する各テストファイルは、別々のチャイルドプロセスで実行されます。同時に実行されるチャイルドプロセスの最大数は、--test-concurrency
フラグによって制御されます。チャイルドプロセスが終了コード 0 で終了した場合、テストは合格ととみなされます。そうでない場合、テストは失敗ととみなされます。テストファイルは Node.js によって実行可能である必要がありますが、内部で node:test
モジュールを使用する必要はありません。
各テストファイルは、通常のスクリプトであるかのように実行されます。つまり、テストファイル自体が node:test
を使用してテストを定義する場合、test()
の concurrency
オプションの値に関係なく、それらのテストはすべて単一のアプリケーションスレッド内で実行されます。
コードカバレッジの収集#
Node.js が --experimental-test-coverage
コマンドラインフラグで起動されると、コードカバレッジが収集され、すべてのテストが完了すると統計情報が報告されます。NODE_V8_COVERAGE
環境変数を使用してコードカバレッジディレクトリを指定すると、生成された V8 カバレッジファイルはそのディレクトリに書き込まれます。Node.js コアモジュールと node_modules/
ディレクトリ内のファイルは、カバレッジレポートに含まれません。カバレッジが有効になっている場合、カバレッジレポートは 'test:coverage'
イベントを介して テストレポーター に送信されます。
カバレッジは、次のコメント構文を使用して、一連の行で無効にすることができます。
/* node:coverage disable */
if (anAlwaysFalseCondition) {
// Code in this branch will never be executed, but the lines are ignored for
// coverage purposes. All lines following the 'disable' comment are ignored
// until a corresponding 'enable' comment is encountered.
console.log('this is never executed');
}
/* node:coverage enable */
カバレッジは、指定された行数についても無効にすることができます。指定された行数を超えると、カバレッジは自動的に再度有効になります。行数が明示的に指定されていない場合は、1 行が無視されます。
/* node:coverage ignore next */
if (anAlwaysFalseCondition) { console.log('this is never executed'); }
/* node:coverage ignore next 3 */
if (anAlwaysFalseCondition) {
console.log('this is never executed');
}
カバレッジレポーター#
tap レポーターと spec レポーターは、カバレッジ統計のサマリーを出力します。また、詳細なカバレッジレポートとして使用できる lcov ファイルを生成する lcov レポーターもあります。
node --test --experimental-test-coverage --test-reporter=lcov --test-reporter-destination=lcov.info
制限事項#
テストランナーのコードカバレッジ機能には、次の制限事項があります。これらは、将来の Node.js リリースで対処されます。
- ソースマップはサポートされていません。
- カバレッジレポートから特定のファイルまたはディレクトリを除外することはサポートされていません。
モッキング#
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.calls.length, 0);
assert.strictEqual(sum(3, 4), 7);
assert.strictEqual(sum.mock.calls.length, 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.calls.length, 0);
assert.strictEqual(sum(3, 4), 7);
assert.strictEqual(sum.mock.calls.length, 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.calls.length, 0);
assert.strictEqual(number.add(3), 8);
assert.strictEqual(number.add.mock.calls.length, 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'll 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);
});
テストレポーター#
node:test
モジュールは、テストランナーが特定のレポーターを使用するための --test-reporter
フラグの受け渡しをサポートしています。
以下の組み込みレポーターがサポートされています。
-
tap
tap
レポーターは、テスト結果を TAP 形式で出力します。 -
spec
spec
レポーターは、テスト結果を読者の理解しやすい形式で出力します。 -
dot
dot
レポーターは、テスト結果をコンパクトな形式で出力します。合格した各テストは `.` で表され、失敗した各テストは `X` で表されます。 -
junit
junit レポーターは、テスト結果を jUnit XML 形式で出力します。 -
lcov
lcov
レポーターは、--experimental-test-coverage
フラグと共に使用された場合、テストカバレッジを出力します。
stdout
が TTY の場合、デフォルトで spec
レポーターが使用されます。それ以外の場合は、デフォルトで `tap` レポーターが使用されます。
これらのレポーターの正確な出力は、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`;
break;
case 'test:enqueue':
yield `test ${event.data.name} enqueued`;
break;
case 'test:watch:drained':
yield 'test watch queue drained';
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';
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`;
break;
case 'test:enqueue':
yield `test ${event.data.name} enqueued`;
break;
case 'test:watch:drained':
yield 'test watch queue drained';
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])
#
options
<Object> テスト実行のための設定オプション。以下のプロパティがサポートされています。concurrency
<number> | <boolean> 数値が指定された場合、その数だけテストプロセスが並列に実行されます。各プロセスは1つのテストファイルに対応します。true
の場合、os.availableParallelism() - 1
個のテストファイルを並列実行します。false
の場合、一度に1つのテストファイルのみを実行します。 デフォルト:false
。files
: <Array> 実行するファイルのリストを含む配列。 デフォルトはテストランナー実行モデルから一致するファイル。inspectPort
<number> | <Function> テスト子プロセスのインスペクターポートを設定します。これは数値、または引数を取らずに数値を返す関数です。 nullish 値が指定された場合、各プロセスはプライマリのprocess.debugPort
からインクリメントされた独自のポートを取得します。 デフォルト:undefined
。only
: <boolean> 真の場合、テストコンテキストはonly
オプションが設定されているテストのみを実行します。setup
<Function>TestsStream
インスタンスを受け取る関数で、テストが実行される前にリスナーを設定するために使用できます。 デフォルト:undefined
。signal
<AbortSignal> 実行中のテストを中止できます。testNamePatterns
<string> | <RegExp> | <Array> 指定されたパターンと一致する名前のテストのみを実行するために使用できる文字列、正規表現、または正規表現の配列。テスト名パターンはJavaScriptの正規表現として解釈されます。実行される各テストについて、beforeEach()
などの対応するテストフックも実行されます。 デフォルト:undefined
。timeout
<number> テスト実行が失敗するまでのミリ秒数。指定しない場合、サブテストはこの値を親から継承します。 デフォルト:Infinity
。watch
<boolean> ウォッチモードで実行するかどうか。 デフォルト:false
。shard
<Object> 特定のシャードでテストを実行します。 デフォルト:undefined
。
- 戻り値: <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);
test([name][, options][, fn])
#
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
。
fn
<Function> | <AsyncFunction> テスト対象の関数。この関数の最初の引数はTestContext
オブジェクトです。テストがコールバックを使用する場合、コールバック関数は2番目の引数として渡されます。 デフォルト: 何もしない関数。- 戻り値: <Promise> テストの完了後に
undefined
で履行されます。テストがdescribe()
内で実行される場合はすぐに履行されます。
test()
関数は、test
モジュールからインポートされた値です。この関数を呼び出すたびに、テストが<TestsStream>に報告されます。
fn
引数に渡される TestContext
オブジェクトは、現在のテストに関連するアクションを実行するために使用できます。たとえば、テストのスキップ、追加の診断情報の追加、サブテストの作成などです。
test()
は、テストが完了すると履行される Promise
を返します。 test()
が describe()
ブロック内で呼び出された場合、すぐに履行されます。戻り値は通常、トップレベルのテストでは破棄できます。ただし、サブテストからの戻り値は、親テストが先に終了してサブテストをキャンセルするのを防ぐために使用する必要があります。次の例を参照してください。
test('top level test', async (t) => {
// The setTimeout() in the following subtest would cause it to outlive its
// parent test if 'await' is removed on the next line. Once the parent test
// completes, it will cancel any outstanding subtests.
await t.test('longer running subtest', 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])
#
name
<string> スイートの名前。テスト結果のレポート時に表示されます。 デフォルト:fn
のname
プロパティ、またはfn
に名前がない場合は'<anonymous>'
。options
<Object> スイートの設定オプション。test([name][, options][, fn])
と同じオプションをサポートします。fn
<Function> | <AsyncFunction> すべてのサブテストとサブスイートを宣言するスイート配下の関数。この関数の最初の引数はSuiteContext
オブジェクトです。 デフォルト: 何もしない関数。- 戻り値: <Promise> すぐに
undefined
で履行されます。
describe()
関数は、node:test
モジュールからインポートされます。この関数を呼び出すたびに、サブテストが作成されます。トップレベルのdescribe
関数を呼び出した後、すべてのトップレベルのテストとスイートが実行されます。
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])
#
スイートを only
としてマークするための省略形。 describe([name], { only: true }[, fn])
と同じです。
it([name][, options][, fn])
#
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])
#
テストを only
としてマークするための省略形。 it([name], { only: true }[, fn])
と同じです。
before([fn][, options])
#
fn
<Function> | <AsyncFunction> フック関数。フックがコールバックを使用する場合、コールバック関数は2番目の引数として渡されます。 デフォルト: 何もしない関数。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])
#
fn
<Function> | <AsyncFunction> フック関数。フックがコールバックを使用する場合、コールバック関数は2番目の引数として渡されます。 デフォルト: 何もしない関数。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])
#
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])
#
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');
});
});
クラス: MockFunctionContext
#
MockFunctionContext
クラスは、MockTracker
API を介して作成されたモックの動作を検査または操作するために使用されます。
ctx.calls
#
モックへの呼び出しを追跡するために使用される内部配列のコピーを返すゲッター。配列の各エントリは、以下のプロパティを持つオブジェクトです。
arguments
<Array> モック関数に渡された引数の配列。error
<any> モック関数が例外をスローした場合、このプロパティにはスローされた値が含まれます。 デフォルト:undefined
。result
<any> モック関数によって返された値。stack
<Error> スタックを使用してモック関数の呼び出し元を特定できるError
オブジェクト。target
<Function> | <undefined> モック関数がコンストラクタの場合、このフィールドには構築されているクラスが含まれます。そうでない場合は、undefined
になります。this
<any> モック関数のthis
値。
ctx.callCount()
#
- 戻り値: <integer> このモックが呼び出された回数。
この関数は、このモックが呼び出された回数を返します。 ctx.calls
は内部呼び出し追跡配列のコピーを作成するゲッターであるため、この関数は ctx.calls.length
をチェックするよりも効率的です。
ctx.mockImplementation(implementation)
#
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])
#
implementation
<Function> | <AsyncFunction>onCall
で指定された呼び出し番号のモックの実装として使用される関数。onCall
<integer>implementation
を使用する呼び出し番号。指定された呼び出しがすでに発生している場合は、例外がスローされます。 デフォルト: 次の呼び出しの番号。
この関数は、1回の呼び出しに対して既存のモックの動作を変更するために使用されます。呼び出し 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()
#
モック関数の呼び出し履歴をリセットします。
ctx.restore()
#
モック関数の実装を元の動作にリセットします。この関数を呼び出した後も、モックを引き続き使用できます。
クラス: MockTracker
#
MockTracker
クラスは、モック機能を管理するために使用されます。テストランナーモジュールは、MockTracker
インスタンスであるトップレベルの mock
エクスポートを提供します。各テストは、テストコンテキストの mock
プロパティを介して独自の MockTracker
インスタンスも提供します。
mock.fn([original[, implementation]][, options])
#
original
<Function> | <AsyncFunction> モックを作成するオプションの関数。 デフォルト: 何もしない関数。implementation
<Function> | <AsyncFunction>original
のモック実装として使用されるオプションの関数。これは、指定された回数の呼び出しに対して1つの動作を示し、次にoriginal
の動作を復元するモックを作成するのに役立ちます。 デフォルト:original
で指定された関数。options
<Object> モック関数のオプションの設定オプション。以下のプロパティがサポートされています。times
<integer> モックがimplementation
の動作を使用する回数。モック関数がtimes
回呼び出されると、自動的にoriginal
の動作が復元されます。この値は、ゼロより大きい整数である必要があります。 デフォルト:Infinity
。
- 戻り値: <Proxy> モック関数。モック関数には、
MockFunctionContext
のインスタンスである特別なmock
プロパティが含まれており、モック関数の動作を検査および変更するために使用できます。
この関数は、モック関数を作成するために使用されます。
次の例では、呼び出しごとにカウンターを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])
#
この関数は、options.getter
が true
に設定された MockTracker.method
の糖衣構文です。
mock.method(object, methodName[, implementation][, options])
#
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
回呼び出されると、自動的に元の動作に戻ります。この値はゼロより大きい整数でなければなりません。 **デフォルト:**Infinity
(無限)。
- 戻り値: <Proxy> モックされたメソッド。モックされたメソッドには、
MockFunctionContext
のインスタンスである特別なmock
プロパティが含まれており、モックされたメソッドの動作を検査および変更するために使用できます。
この関数は、既存のオブジェクトメソッドにモックを作成するために使用されます。次の例は、既存のオブジェクトメソッドにモックを作成する方法を示しています。
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.calls.length, 0);
assert.strictEqual(number.subtract(3), 2);
assert.strictEqual(number.subtract.mock.calls.length, 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.reset()
#
この関数は、この MockTracker
によって以前に作成されたすべてのモックのデフォルトの動作を復元し、モックを MockTracker
インスタンスから切り離します。切り離された後もモックは使用できますが、MockTracker
インスタンスを使用して動作をリセットしたり、他の方法で操作することはできなくなります。
各テストの完了後、テストコンテキストの MockTracker
でこの関数が呼び出されます。グローバル MockTracker
が広範囲に使用されている場合は、この関数を手動で呼び出すことをお勧めします。
mock.restoreAll()
#
この関数は、この MockTracker
によって以前に作成されたすべてのモックのデフォルトの動作を復元します。 mock.reset()
とは異なり、mock.restoreAll()
はモックを MockTracker
インスタンスから切り離しません。
mock.setter(object, methodName[, implementation][, options])
#
この関数は、options.setter
が true
に設定された MockTracker.method
の糖衣構文です。
クラス: MockTimers
#
タイマーのモッキングは、ソフトウェアテストで一般的に使用される手法であり、 `setInterval` や `setTimeout` などのタイマーの動作を、指定された時間間隔を実際に待たずにシミュレートおよび制御するために使用されます。
MockTimers は Date
オブジェクトもモックできます。
MockTracker
は、MockTimers
インスタンスであるトップレベルの timers
エクスポートを提供します。
timers.enable([enableOptions])
#
指定されたタイマーのタイマーモッキングを有効にします。
enableOptions
<Object> タイマーモッキングを有効にするためのオプション設定。以下のプロパティがサポートされています。apis
<Array> モックするタイマーを含むオプションの配列。現在サポートされているタイマー値は、'setInterval'
、'setTimeout'
、'setImmediate'
、および'Date'
です。 **デフォルト:**['setInterval', 'setTimeout', 'setImmediate', 'Date']
。配列が指定されていない場合、すべての時間関連 API('setInterval'
、'clearInterval'
、'setTimeout'
、'clearTimeout'
、および'Date'
)がデフォルトでモックされます。now
<number> | <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'
)がモックされます。 node:timers
、node:timers/promises
、および globalThis
からの setInterval
、clearInterval
、setTimeout
、および clearTimeout
関数がモックされます。グローバル Date
オブジェクトも同様です。
timers.reset()
#
この関数は、この 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)
#
すべてのモックされたタイマーの時間を進めます。
milliseconds
<number> タイマーを進める時間(ミリ秒単位)。
**注:** これは、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);
// 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();
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);
});
あるいは、.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 twoSeconds = 3000;
context.mock.timers.tick(twoSeconds);
context.mock.timers.tick(twoSeconds);
context.mock.timers.tick(twoSeconds);
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 twoSeconds = 3000;
context.mock.timers.tick(twoSeconds);
context.mock.timers.tick(twoSeconds);
context.mock.timers.tick(twoSeconds);
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);
// Advance in time
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);
// Advance in time
context.mock.timers.tick(9999);
assert.strictEqual(fn.mock.callCount(), 1);
assert.strictEqual(Date.now(), 9999);
});
クリア関数の使用#
前述のように、タイマーのすべてのクリア関数(clearTimeout
および clearInterval
)は暗黙的にモックされます。 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);
// Implicity mocked as well
clearTimeout(id);
context.mock.timers.tick(9999);
// As that setTimeout was cleared the mock function will never be called
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);
// Implicity mocked as well
clearTimeout(id);
context.mock.timers.tick(9999);
// As that setTimeout was cleared the mock function will never be called
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);
// Advance in time
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);
// Advance in time
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()
#
保留中のすべてのモックされたタイマーをすぐにトリガーします。 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)
#
モックされた 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 functions following the given order', (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, []);
// The date is advanced but the timers don't tick
assert.strictEqual(Date.now(), 12000);
});
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);
assert.deepStrictEqual(results, []);
context.mock.timers.setTime(12000);
assert.deepStrictEqual(results, []);
// The date is advanced but the timers don't tick
assert.strictEqual(Date.now(), 12000);
});
クラス: TestsStream
#
- <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> 関数カバレッジを表す関数の配列。branches
<Array> 分岐カバレッジを表す分岐の配列。lines
<Array> 行番号とカバレッジされた回数を表す行の配列。
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:dequeue'
#
data
<Object>column
<number> | <undefined> テストが定義されている列番号。REPLでテストが実行された場合は`undefined`。file
<string> | <undefined> テストファイルのパス。REPLでテストが実行された場合は`undefined`。line
<number> | <undefined> テストが定義されている行番号。REPLでテストが実行された場合は`undefined`。name
<string> テスト名。nesting
<number> テストのネストレベル。
テストがキューから削除され、実行される直前に発行されます。
イベント: '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
が呼び出されたときに発行されます。
イベント: 'test:enqueue'
#
data
<Object>column
<number> | <undefined> テストが定義されている列番号。REPLでテストが実行された場合は`undefined`。file
<string> | <undefined> テストファイルのパス。REPLでテストが実行された場合は`undefined`。line
<number> | <undefined> テストが定義されている行番号。REPLでテストが実行された場合は`undefined`。name
<string> テスト名。nesting
<number> テストのネストレベル。
テストが実行のためにキューに入れられたときに発行されます。
イベント: `'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: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: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:stderr'
#
data
<Object>column
<number> | <undefined> テストが定義されている列番号。REPLでテストが実行された場合は`undefined`。file
<string> テストファイルのパス。line
<number> | <undefined> テストが定義されている行番号。REPLでテストが実行された場合は`undefined`。message
<string> `stderr` に書き込まれたメッセージ。
実行中のテストが `stderr` に書き込んだときに発行されます。このイベントは、`--test` フラグが渡された場合にのみ発行されます。
イベント: 'test:stdout'
#
data
<Object>column
<number> | <undefined> テストが定義されている列番号。REPLでテストが実行された場合は`undefined`。file
<string> テストファイルのパス。line
<number> | <undefined> テストが定義されている行番号。REPLでテストが実行された場合は`undefined`。message
<string> `stdout` に書き込まれたメッセージ。
実行中のテストが `stdout` に書き込んだときに発行されます。このイベントは、`--test` フラグが渡された場合にのみ発行されます。
イベント: 'test:watch:drained'
#
ウォッチモードで実行のためにキューに入れられたテストがなくなったときに発行されます。
クラス: TestContext
#
`TestContext` のインスタンスは、テストランナーと対話するために各テスト関数に渡されます。ただし、`TestContext` コンストラクターは API の一部として公開されていません。
context.before([fn][, options])
#
fn
<Function> | <AsyncFunction> フック関数。この関数の最初の引数は `TestContext` オブジェクトです。フックがコールバックを使用する場合、コールバック関数は2番目の引数として渡されます。 **デフォルト:** 何もしない関数。options
<Object> フックの設定オプション。以下のプロパティがサポートされています。signal
<AbortSignal> 実行中のフックを中止できます。timeout
<number> フックが失敗するまでのミリ秒数。指定されていない場合、サブテストは親からこの値を継承します。 デフォルト:Infinity
。
この関数は、現在のテストのサブテストの前に実行されるフックを作成するために使用されます。
context.beforeEach([fn][, options])
#
fn
<Function> | <AsyncFunction> フック関数。この関数の最初の引数は `TestContext` オブジェクトです。フックがコールバックを使用する場合、コールバック関数は2番目の引数として渡されます。 **デフォルト:** 何もしない関数。options
<Object> フックの設定オプション。以下のプロパティがサポートされています。signal
<AbortSignal> 実行中のフックを中止できます。timeout
<number> フックが失敗するまでのミリ秒数。指定されていない場合、サブテストは親からこの値を継承します。 デフォルト:Infinity
。
この関数は、現在のテストの各サブテストの前に実行されるフックを作成するために使用されます。
test('top level test', async (t) => {
t.beforeEach((t) => t.diagnostic(`about to run ${t.name}`));
await t.test(
'This is a subtest',
(t) => {
assert.ok('some relevant assertion here');
},
);
});
context.after([fn][, options])
#
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])
#
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.diagnostic(message)
#
message
<string> レポートされるメッセージ。
この関数は、出力に診断情報を書き込むために使用されます。診断情報は、テスト結果の最後に含まれます。この関数は値を返しません。
test('top level test', (t) => {
t.diagnostic('A diagnostic message');
});
`context.name` #
テストの名前。
`context.runOnly(shouldRunOnlyTests)` #
- `shouldRunOnlyTests` <boolean> `only` オプションが設定されたテストのみを実行するかどうか。
`shouldRunOnlyTests` が真の場合、テストコンテキストは `only` オプションが設定されたテストのみを実行します。そうでない場合、すべてのテストが実行されます。Node.js が `--test-only` コマンドラインオプションで起動されていない場合、この関数は何も実行しません。
test('top level test', (t) => {
// The test context can be set to run subtests with the 'only' option.
t.runOnly(true);
return Promise.all([
t.test('this subtest is now skipped'),
t.test('this subtest is run', { only: true }),
]);
});
`context.signal` #
テストが中断されたときに、テストのサブタスクを中断するために使用できます。
test('top level test', async (t) => {
await fetch('some/uri', { signal: t.signal });
});
`context.skip([message])` #
- `message` <string> 省略可能なスキップメッセージ。
この関数は、テストの出力がテストをスキップ済みとして示すようにします。`message` が指定されている場合、出力に含まれます。 `skip()` を呼び出しても、テスト関数の��行は終了しません。この関数は値を返しません。
test('top level test', (t) => {
// Make sure to return here as well if the test contains additional logic.
t.skip('this is skipped');
});
`context.todo([message])` #
- `message` <string> 省略可能な `TODO` メッセージ。
この関数は、テストの出力に `TODO` ディレクティブを追加します。`message` が指定されている場合、出力に含まれます。 `todo()` を呼び出しても、テスト関数の��行は終了しません。この関数は値を返しません。
test('top level test', (t) => {
// This test is marked as `TODO`
t.todo('this is a todo');
});
`context.test([name][, options][, fn])` #
- `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
。
fn
<Function> | <AsyncFunction> テスト対象の関数。この関数の最初の引数はTestContext
オブジェクトです。テストがコールバックを使用する場合、コールバック関数は2番目の引数として渡されます。 デフォルト: 何もしない関数。- 戻り値: <Promise> テストが完了すると `undefined` で履行されます。
この関数は、現在のテストの下にサブテストを作成するために使用されます。この関数は、トップレベルの `test()` 関数と同じように動作します。
test('top level test', async (t) => {
await t.test(
'This is a subtest',
{ only: false, skip: false, concurrency: 1, todo: false },
(t) => {
assert.ok('some relevant assertion here');
},
);
});
クラス: `SuiteContext` #
`SuiteContext` のインスタンスは、テストランナーと対話するために各スイート関数に渡されます。ただし、`SuiteContext` コンストラクターは API の一部として公開されていません。
`context.name` #
スイートの名前。
`context.signal` #
テストが中断されたときに、テストのサブタスクを中断するために使用できます。