Rspackのテスト
Rspackのテストケースには以下が含まれます
- Rspackコアのテストケースは、`packages/rspack-test-tools/tests`フォルダに格納されており、ビルドプロセスをシミュレートしてテストケースを実行します。一般的に、テストケースはこのフォルダに追加する必要があります。
- 他のRspackパッケージのテストケースは、`packages/{name}/tests`フォルダに格納されており、そのパッケージを変更する場合のみ追加または変更する必要があります。
テストの実行
これらのテストケースは、以下の方法で実行できます。
- ルートディレクトリから`./x test unit`または`pnpm run test:unit`を実行します。
- または、`packages/rspack-test-tools`ディレクトリから`npm run test`を実行します。
- スナップショットを更新するには、`packages/rspack-test-tools`ディレクトリから`npm run test -- -u`を実行します。
- 特定のjest cli引数を渡すには、`packages/rspack-test-tools`ディレクトリから`npm run test -- {args}`を実行します。
- 特定のテストケースをフィルタリングするには、`packages/rspack-test-tools`ディレクトリから`npm run test -- -t path-of-spec`を実行します。
- `packages/rspack-test-tools/configCases/asset`フォルダのテストケースのみを実行するには、`npm run test -- -t config/asset`のように実行します(configは自動的にconfigCasesにマッピングされ、他のフォルダも同様の方法で動作します)。
ディレクトリ構造
`packages/rspack-test-tools/tests`フォルダの構造は以下のとおりです。
.
├── js # Used to store build artifacts and temporary files
├── __snapshots__ # Used to store test snapshots
├── {Name}.test.js # Entry for normal testing
├── {Name}.hottest.js # Entry for hot snapshot testing
├── {Name}.difftest.js # Entry for diff testing
├── {name}Cases # Directory to store test cases
└── fixtures # General test files
`{Name}.test.js`はテストのエントリファイルであり、`{name}Cases`フォルダを走査してその中のケースを実行します。そのため、テストケースを追加または変更する必要がある場合は、テストの種類に基づいて関連する`{name}Cases`フォルダに追加します。
テストの種類
既存のテストの種類は以下のとおりです。
- 標準:設定変更なしでコアビルドプロセスをテストするために使用します。`rspack.config.js`を追加する必要がないテストの場合に使用します。
- 設定:ビルド設定オプションをテストするために使用します。テストで`rspack.config.js`を介して追加された特定の設定が必要で、他のシナリオに当てはまらない場合は、このテストの種類を使用します。
- ホットモジュール置換(HMR):ホットモジュール置換(HMR)が正しく実行されるかどうかをテストするために使用します。このタイプには、固定`target=async-node`のHotNode、固定`target=web`のHotWeb、固定`target=webworker`のHotWorkerが含まれます。
- ホットスナップショット:HMRが正しい中間アーティファクトを生成できるかどうかをテストするために使用します。このテストタイプはHotタイプとテストケースを共有し、各HMRの増分アーティファクトのスナップショットを生成します。
- ウォッチ:ウォッチモードでファイルを修正した後の増分コンパイルをテストするために使用します。
- 統計出力:ビルド終了後のコンソール出力ログをテストするために使用します。
- 統計API:ビルド終了後に生成されたStatsオブジェクトをテストするために使用します。
- 診断:ビルドプロセス中に生成された警告/エラーのフォーマットされた出力情報をテストするために使用します。
- ハッシュ:ハッシュ生成が正しく機能するかどうかをテストするために使用します。
- コンパイラ:Compiler/CompilationオブジェクトAPIをテストするために使用します。
- デフォルト:設定オプション間の相互作用をテストするために使用します。
- エラー:`compilation.errors`と`compilation.warnings`間の相互作用をテストするために使用します。
- フック:様々なフック機能をテストするために使用します。
- ツリーシェイキング:ツリーシェイキング関連の機能をテストするために使用します。
- ビルトイン:ビルトインネイティブ実装を持つプラグインをテストするために使用します。
上記のテストタイプ内でテストケースを追加することを優先してください。
標準
テストエントリ |
tests/Normal.test.js |
ケースディレクトリ |
tests/normalCases |
出力ディレクトリ |
tests/js/normal |
デフォルト設定 |
NormalProcessor |
実行出力 |
はい |
ケースの書き方は通常のRspackプロジェクトと同じですが、`rspack.config.js`ファイルは含まれず、ビルドには提供された設定を使用します。
設定
テストエントリ |
tests/Config.test.js |
ケースディレクトリ |
tests/configCases |
出力ディレクトリ |
tests/js/config |
デフォルト設定 |
ConfigProcessor |
実行出力 |
はい |
このテストケースは通常のRspackプロジェクトに似ています。`rspack.config.js`を追加してビルド設定を指定し、`test.config.js`を追加することでテスト中の様々な動作を制御できます。`test.config.js`ファイルの構造は以下のとおりです。
test.config.js
1type TConfigCaseConfig = {
2 noTest?: boolean; // Do not run the test output and end the test
3 beforeExecute?: () => void; // Callback before running the output
4 afterExecute?: () => void; // Callback after running the output
5 moduleScope?: (ms: IBasicModuleScope) => IBasicModuleScope; // Module context variables when running the output
6 findBundle?: (
7 // Function for obtaining output when running the output, can control the output at a finer granularity
8 index: number, // Compiler index in multi-compiler scenario
9 options: TCompilerOptions<T>, // Build configuration object
10 ) => string | string[];
11 bundlePath?: string[]; // Output file name when running the output (prior to findBundle)
12 nonEsmThis?: (p: string | string[]) => Object; // this object during CJS output runtime, defaults to current module's module.exports if not specified
13 modules?: Record<string, Object>; // Pre-added modules when running the output, will be prioritized when required
14 timeout?: number; // Timeout for the test case
15};
16
17/** @type {import("../../../..").TConfigCaseConfig} */
18module.exports = {
19 // ...
20};
ホットモジュール置換(HMR)
テストエントリ |
Hot{Target}.test.js |
ケースディレクトリ |
tests/hotCases |
出力ディレクトリ |
tests/js/hot-{target} |
デフォルト設定 |
HotProcessor |
実行出力 |
はい |
このテストケースは通常のRspackプロジェクトに似ています。`rspack.config.js`を追加してビルド設定を指定できます。
また、変更されたファイル内では、`---`を使用して変更前後のコードを区切ります。
file.js
module.exports = 1; // Initial build
---
module.exports = 2; // First hot update
---
module.exports = 3; // Second hot update
テストケースコードでは、`NEXT`メソッドを使用してファイル変更のタイミングを制御し、その中にテストコードを追加します。
index.js
import value from './file';
it('should hot update', done => {
expect(value).toBe(1);
// Use packages/rspack-test-tools/tests/hotCases/update.js to trigger update
NEXT(
require('../../update')(done, true, () => {
expect(value).toBe(2);
NEXT(
require('../../update')(done, true, () => {
expect(value).toBe(3);
done();
}),
);
}),
);
});
module.hot.accept('./file');
ホットスナップショット
テストエントリ |
HotSnapshot.hottest.js |
ケースディレクトリ |
tests/hotCases |
出力ディレクトリ |
tests/js/hot-snapshot |
デフォルト設定 |
ホットモジュール置換(HMR)と同じ |
実行出力 |
はい |
`Hot{Target}`と同じテストケースを使用し、ケースフォルダに`__snapshots__/{target}/{step}.snap.txt`ファイルを作成して、各HMRの増分アーティファクトのスナップショットテストを実行します。
スナップショットの構造は以下のとおりです。
- 変更されたファイル:このHMRビルドをトリガーしたソースコードファイル
- アセットファイル:このHMRビルドのアーティファクトファイル
- マニフェスト:このHMRビルドの`hot-update.json`メタデータファイルの内容。ここで
- `"c"`:このHMRで更新されるチャンクのID
- `"r"`:このHMRで削除されるチャンクのID
- `"m"`:このHMRで削除されるモジュールのID
- アップデート:このHMRビルドの`hot-update.js`パッチファイルに関する情報。これには
- 変更されたモジュール:パッチに含まれるモジュールのリスト
- 変更されたランタイムモジュール:パッチに含まれるランタイムモジュールのリスト
- 変更されたコンテンツ:パッチコードのスナップショット
ウォッチ
エントリファイル |
Watch.test.js |
ケースディレクトリ |
tests/watchCases |
出力ディレクトリ |
tests/js/watch |
デフォルト設定 |
WatchProcessor |
実行出力 |
はい |
ウォッチビルドは複数ステップで実行する必要があるため、`rspack.config.js`を追加してビルド設定を指定できます。そのケースのディレクトリ構造は特殊で、変更バッチを表すために増加する番号を使用します。
.
├── 0 # WATCH_STEP=0, initial code for the case
├── 1 # WATCH_STEP=1, diff files for the first change
├── 2 # WATCH_STEP=2, diff files for the second change
└── rspack.config.js
テストコードでは、`WATCH_STEP`変数を使用して、現在の変更バッチ番号を取得できます。
統計出力
テストエントリ |
StatsOutput.test.js |
ケースディレクトリ |
tests/statsOutputCases |
出力ディレクトリ |
tests/js/statsOutput |
デフォルト設定 |
StatsProcessor |
実行出力 |
いいえ |
ケースの書き方は通常のRspackプロジェクトと同じです。実行後、コンソール出力情報はスナップショットにキャプチャされ、`rspack-test-tools/tests/__snapshots__/StatsOutput.test.js.snap`に保存されます。
ヒント
一部のStatsOutputテストケースにはハッシュが含まれているため、出力コードを変更する際は、-u
パラメーターを使用してこれらのケースのスナップショットを更新してください。
Stats API
エントリファイル |
StatsAPI.test.js |
ケースディレクトリ |
tests/statsAPICases |
出力ディレクトリ |
なし |
デフォルト設定 |
なし |
実行出力 |
いいえ |
このテストは、ビルドのソースコードとしてrspack-test-tools/tests/fixtures
を使用するため、テストケースは単一ファイルとして記述されています。その構造は以下のとおりです。
{case}.js
1type TStatsAPICaseConfig = {
2 description: string, // Case description
3 options?: (context: ITestContext) => TCompilerOptions<T>, // Case build configuration
4 build?: (context: ITestContext, compiler: TCompiler<T>) => Promise<void>, // Case build method
5 check?: (stats: TCompilerStats<T>, compiler: TCompiler<T>) => Promise<void>, // Function to check the stats for the case
6};
7
8/** @type {import('../..').TStatsAPICaseConfig} */
9module.exports = {
10 // ...
11};
診断
エントリファイル |
Diagnostics.test.js |
ケースディレクトリ |
tests/diagnosticsCases |
出力ディレクトリ |
tests/js/diagnostics |
デフォルト設定 |
DiagnosticProcessor |
実行出力 |
いいえ |
このテストケースは一般的なrspackプロジェクトと同様で、rspack.config.js
を追加することでビルド設定を指定できます。さらに、警告/エラーのスナップショットを保存するために、ケースディレクトリにstats.err
ファイルが追加されます。更新するには、-u
パラメーターを使用してください。
ハッシュ
エントリファイル |
Hash.test.js |
ケースディレクトリ |
tests/hashCases |
出力ディレクトリ |
なし |
デフォルト設定 |
HashProcessor |
実行出力 |
いいえ |
このテストケースは一般的なrspackプロジェクトと同様ですが、ケースディレクトリにtest.config.js
ファイルを追加し、ビルドが完了した後にstats
オブジェクト内のハッシュ情報をチェックするvalidate()
メソッドを指定します。
test.config.js
1type THashCaseConfig = {
2 validate?: (stats: TCompilerStats<T>) => void,
3};
4
5/** @type {import('../..').THashCaseConfig} */
6module.exports = {
7 // ...
8};
コンパイラ
エントリファイル |
Compiler.test.js |
ケースディレクトリ |
tests/compilerCases |
出力ディレクトリ |
なし |
デフォルト設定 |
なし |
実行出力 |
いいえ |
このテストは、ビルドのソースコードとしてrspack-test-tools/tests/fixtures
を使用するため、テストケースは単一ファイルとして記述されています。その構造は以下のとおりです。
{case.js}
1interface TCompilerCaseConfig {
2 description: string; // Description of the test case
3 options?: (context: ITestContext) => TCompilerOptions<T>; // Test case build configuration
4 compiler?: (context: ITestContext, compiler: TCompiler<T>) => Promise<void>; // How the compiler is created for the test case
5 build?: (context: ITestContext, compiler: TCompiler<T>) => Promise<void>; // Build method for the test case
6 check?: (
7 context: ITestContext,
8 compiler: TCompiler<T>,
9 stats: TCompilerStats<T>,
10 ) => Promise<void>; // Check function for the test case
11}
12
13/** @type {import('../..').TCompilerCaseConfig} */
14module.exports = {
15 // ...
16};
デフォルト
エントリファイル |
Defaults.test.js |
ケースディレクトリ |
tests/defaultCases |
出力ディレクトリ |
なし |
デフォルト設定 |
なし |
実行出力 |
いいえ |
このテストは実際のビルドを実行しません。ビルド設定を生成し、デフォルト設定との違いを観察するだけです。基本的なデフォルト設定はスナップショットとしてrspack-test-tools/tests/__snapshots__/Defaults.test.js.snap
に保存されます。
このテストは、ビルドのソースコードとしてrspack-test-tools/tests/fixtures
を使用するため、テストケースは単一ファイルとして記述されています。その構造は以下のとおりです。
{case}.js
1interface TDefaultsCaseConfig {
2 description: string; // Description of the test case
3 cwd?: string; // process.cwd for generating the build configuration of the test case, default is the `rspack-test-tools` directory
4 options?: (context: ITestContext) => TCompilerOptions<ECompilerType.Rspack>; // Test case build configuration
5 diff: (
6 diff: jest.JestMatchers<Diff>,
7 defaults: jest.JestMatchers<TCompilerOptions<ECompilerType.Rspack>>,
8 ) => Promise<void>; // Differences from the default configuration
9}
10
11/** @type {import('../..').TDefaultsCaseConfig} */
12module.exports = {
13 // ...
14};
エラーテストの詳細を以下に示します。
エラー
エントリファイル |
Error.test.js |
ケースディレクトリ |
tests/errorCases |
出力ディレクトリ |
なし |
デフォルト設定 |
ErrorProcessor |
実行出力 |
いいえ |
このテストは、ビルドのソースコードとしてrspack-test-tools/tests/fixtures
を使用するため、テストケースは単一ファイルとして記述されています。その構造は以下のとおりです。
{case}.js
1interface TErrorCaseConfig {
2 description: string; // Description of the test case
3 options?: (
4 options: TCompilerOptions<T>,
5 context: ITestContext,
6 ) => TCompilerOptions<T>; // Test case configuration
7 build?: (context: ITestContext, compiler: TCompiler<T>) => Promise<void>; // Test case build method
8 check?: (stats: TStatsDiagnostics) => Promise<void>; // Function to check the test case
9}
10
11/** @type {import('../..').TErrorCaseConfig} */
12module.exports = {
13 // ...
14};
フック
エントリファイル |
Hook.test.js |
ケースディレクトリ |
tests/hookCases |
出力ディレクトリ |
なし |
デフォルト設定 |
HookProcessor |
実行出力 |
いいえ |
このテストはフックの入出力記録し、hooks.snap.txt
のスナップショットに保存します。最終的な製品コードのスナップショットはoutput.snap.txt
に保存されます。
このテストは、ビルドのソースコードとしてrspack-test-tools/tests/fixtures
を使用するため、テストケースは単一ファイルとして記述されています。その構造は以下のとおりです。
{case}/test.js
1interface THookCaseConfig {
2 description: string; // Description of the test case
3 options?: (
4 options: TCompilerOptions<T>,
5 context: ITestContext,
6 ) => TCompilerOptions<T>; // Test case configuration
7 compiler?: (context: ITestContext, compiler: TCompiler<T>) => Promise<void>; // Callback after creating the compiler instance
8 check?: (context: ITestContext) => Promise<void>; // Callback after the build is completed
9}
10
11/** @type {import("../../../..").THookCaseConfig} */
12module.exports = {
13 // ...
14};
ツリーシェイキング
エントリファイル |
TreeShaking.test.js |
ケースディレクトリ |
tests/treeShakingCases |
出力ディレクトリ |
tests/js/treeShaking |
デフォルト設定 |
TreeShakingProcessor |
実行出力 |
いいえ |
このテストケースでは、設定は通常のrspackプロジェクトと同様です。rspack.config.js
を追加することでビルド設定を指定できますが、最終的な製品はスナップショットとして__snapshots__/treeshaking.snap.txt
に保存されます。
組み込み
エントリファイル |
Builtin.test.js |
ケースディレクトリ |
tests/builtinCases |
出力ディレクトリ |
tests/js/builtin |
デフォルト設定 |
BuiltinProcessor |
実行出力 |
いいえ |
このテストケースは通常のrspackプロジェクトと同様で、rspack.config.js
を追加することでビルド設定を指定できます。ただし、ディレクトリによっては、製品のスナップショットが異なり、__snapshots__/output.snap.txt
に保存されます。
- plugin-css:
.css
拡張子のファイルのスナップショット
- plugin-css-modules:
.css
と.js
拡張子のファイルのスナップショット
- plugin-html:
.html
拡張子のファイルのスナップショット
- その他:
.js
拡張子のファイルのスナップショット