测试 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。
- 例如
npm run test -- -t config/asset 只运行 packages/rspack-test-tools/configCases/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) 是否正常运行。 此类型包括具有固定
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};
热更新
| 测试入口 |
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 |
| 默认配置 |
与 热更新 相同 |
| 运行输出 |
是 |
使用与 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 参数来更新这些用例的快照。
统计 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文件,并在构建完成后指定一个validate()方法来检查stats对象中的哈希信息。
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
| 入口文件 |
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扩展名的文件的快照