For AI agents: the complete documentation index is available at https://rstest.rs/zh/llms.txt, the full documentation bundle is available at https://rstest.rs/zh/llms-full.txt, and this page is available as Markdown at https://rstest.rs/zh/blog/announcing-0-12.md.
close
  • 简体中文
  • Rstest 0.12 发布

    2026 年 9 月 14 日

    9aoy
    9aoy
    @9aoy
    Max
    Max
    @fi3ework
    Rstest 0.12

    我们很高兴地宣布 Rstest 0.12 已经正式发布!

    Rstest 0.12 新增 E2E 与 Module Federation 测试支持,通过 VM pool 和 test environment prebundle 提升大型测试套件性能,并正式推出新的 JavaScript API。

    0.12 版本的主要改进包括:

    支持 E2E 测试

    Rstest 0.12 通过 @rstest/playwright 集成 Playwright 支持 E2E 测试,使单元测试、组件测试与 E2E 测试可以共用一份 Rstest 的配置、命令和 reporter。

    你可以直接在 Rstest 里写 E2E 测试:用 Playwright 打开真实页面,验证本地 dev server、preview server 或线上 URL 的完整流程。完整项目可以参考 Rstest E2E 示例。

    要开始编写 E2E 测试,从 @rstest/playwright 导入 test 与 expect 即可:

    e2e.test.ts
    import { expect, test } from '@rstest/playwright';
    
    test('page title', async ({ page }) => {
      await page.goto('https://example.com');
    
      await expect(page).toHaveTitle(/Example/);
      await expect(page.locator('h1')).toHaveText('Example Domain');
    });

    通过 definePlaywrightConfig,可以复用与 Playwright 一致的默认配置,同时按需自定义 Playwright 相关选项。例如,可以设置默认 viewport,并在 CI 重试时记录 trace:

    rstest.config.ts
    import { defineConfig } from '@rstest/core';
    import { definePlaywrightConfig } from '@rstest/playwright/config';
    
    export default defineConfig({
      retry: process.env.CI ? 1 : 0,
      extends: definePlaywrightConfig({
        contextOptions: {
          viewport: { width: 1440, height: 900 },
        },
        trace: process.env.CI ? 'on-first-retry' : 'off',
      }),
    });

    已有的 Playwright Test 项目可以借助 migrate-to-rstest skill 迁移,它包含针对 Playwright 配置、fixture 与行为差异的迁移指引。

    参考 E2E 测试 了解更多。

    支持 Module Federation 测试

    Rstest 0.12 支持测试 Module Federation 应用。测试代码可以像消费者应用一样直接导入远程模块,Rstest 会真正加载生产者暴露的模块并解析共享依赖,消费者与生产者之间的集成问题在单元测试阶段就能发现,不必等到联调或上线。

    在 Rstest 的 Node、jsdom、happy-dom、browser mode 模式中,均支持 Module Federation。完整项目可以参考 Node 示例与 browser mode 示例。

    要在项目中接入 Module Federation 测试,使用 @module-federation/rstest 插件,在配置中注册并声明远程模块与共享依赖即可:

    rstest.config.ts
    import { federation } from '@module-federation/rstest';
    import { defineConfig } from '@rstest/core';
    
    export default defineConfig({
      testEnvironment: 'jsdom',
      plugins: [
        federation({
          name: 'host',
          remotes: {
            'component-app': 'component_app@http://localhost:3001/remoteEntry.cjs',
          },
          shared: {
            react: { singleton: true },
            'react-dom': { singleton: true },
          },
        }),
      ],
    });

    之后像应用代码一样导入暴露的模块:

    remote.test.ts
    import { expect, it } from '@rstest/core';
    
    it('loads a federated remote', async () => {
      const remote = await import('component-app/Button');
      expect(remote.default).toBeDefined();
    });

    参考 Module Federation 了解更多。

    新增 vmThreads 与 vmForks pool

    对于大量 jsdom / happy-dom 测试文件,Rstest 0.12 新增的 vmThreads / vmForks 可以显著减少 worker 启动和模块加载开销。它们在测试文件之间复用 worker,同时为每个文件创建一个新的 vm.Context。文件仍然各自拥有独立的 JavaScript realm 与模块图,而 worker 启动、依赖解析和 V8 编译这些开销由多个文件共享。

    在一个 2,400 个文件、20,000 个测试的 jsdom benchmark 项目中(15 个 worker,每个进程从空 cache 启动):

    forks315.17s
    vmThreads快 9.5 倍33.22s

    Rstest 目前提供四种 pool,可根据测试场景选择:

    Pool适用场景限制
    forks默认选择;适合 native addon、process.chdir() 等场景大型 DOM 测试套件启动开销较高
    threads测试文件多且执行较轻不支持部分进程级能力
    vmThreads大量 jsdom / happy-dom 测试,性能最佳存在跨 realm 与自定义 loader 限制
    vmForks兼顾 VM pool 性能与进程能力需避免进程级状态残留

    切换前建议先确认瓶颈确实在 worker 启动或模块加载,setup 中的数据库初始化、网络请求等开销不会因更换 pool 而减少。通过 pool.type 启用:

    rstest.config.ts
    import { defineConfig } from '@rstest/core';
    
    export default defineConfig({
      pool: {
        type: 'vmThreads',
        memoryLimit: '256MB',
      },
    });

    测试文件很多时,可以用 pool.memoryLimit 限制单个 worker 的内存占用,超过阈值 Rstest 会自动换新 worker。

    参考如何选择 pool 类型了解完整的选择依据,以及 VM pool 的兼容范围。

    更快的 jsdom / happy-dom 加载

    除了通过 VM pool 降低 worker 开销,0.12 还支持并默认开启预打包 test environment,减少 jsdom / happy-dom 的重复加载成本。

    此前每个 worker 都要通过 Node.js 的模块系统各自加载 jsdom 或 happy-dom,把环境里的所有模块文件逐个解析并执行。开启 prebundle 后,Rstest 先把环境构建成一份 ESM bundle,所有 worker 共用这一份,重复的解析与初始化基本被省掉。100 个文件、1,000 个测试的基准:

    jsdom 30.0.1

    直接加载16.99s
    Prebundle-37.8%10.57s

    happy-dom 20.11.1

    直接加载6.35s
    Prebundle-53.0%2.98s

    从 0.12 版本开始,testEnvironment.prebundle 默认为 'auto',Rstest 会对 jsdom 15–26、29–30 和 happy-dom 20 进行预打包。其他版本继续直接加载;prebundle 构建、加载或校验失败时也会回退到直接加载。如果你的环境在打包后行为不一致,可以显式关闭:

    rstest.config.ts
    import { defineConfig } from '@rstest/core';
    
    export default defineConfig({
      testEnvironment: {
        name: 'jsdom',
        prebundle: false,
      },
    });

    参考 Environment prebundle 了解更多。

    全新的 JavaScript API

    Rstest 0.12 提供了全新的 createRstest API,这是 1.0 之前对 JavaScript API 进行的一次重写,方便将 Rstest 集成到工具、IDE 或其他 Node.js 程序中。它与 rstest 命令共用同一套核心执行能力,可以通过代码运行、watch、列举测试和合并 blob report。

    你可以使用 createRstest() 创建一个实例,并使用实例的 run、watch、listTests 与 mergeReports 等方法调用 Rstest 的具体功能。

    import { createRstest } from '@rstest/core/api';
    
    const rstest = await createRstest({
      cwd: './packages/app',
      config: {
        include: ['src/**/*.test.ts'],
        reporters: [],
      },
    });
    
    const result = await rstest.run();
    console.log(result.status, result.summary);

    输出结果:

    pass {
      tests: { total: 1, passed: 1, failed: 0, skipped: 0, todo: 0 },
      files: { total: 1, failed: 0 },
    }

    参考 Rstest instance 了解更多。

    其他改进

    • file 与 worker 作用域的 fixture。 test.extend 的 fixture 可以按文件或按 worker 共享一个实例,数据库连接、浏览器实例这类代价昂贵的准备工作不必每个测试重做一遍。参考 test.extend。
    • --onlyFailures 只重跑失败的文件。 Rstest 会记住上次失败的文件,修完只跑这些,不必重跑整个套件;同一份记录还会把失败和耗时长的文件排在前面,反馈更加及时。参考 onlyFailures。
    • Rspack 原生 watcher。 watch 模式改用 Rspack 的 Rust 文件 watcher,增量检测变更,大量文件同时变化时也能保持稳定与响应速度。参考 rstest watch。
    • 超时时的 context.signal。 每次测试尝试都会拿到一个 AbortSignal,超时后能及时取消挂起的 fetch 等请求,不再拖住 worker。参考 signal。
    • task metadata。 测试、suite 和文件可以携带自定义元数据,方便按 owner、模块等维度分组统计。参考 Metadata。
    • expect.poll 的默认值。 在配置里统一设置轮询的 timeout 与 interval,不必在每个 expect.poll() 上重复传参。参考 expect.poll。
    • Rsbuild 插件可以读取和修改 Rstest 配置。 框架或工具的 Rsbuild 插件可以自动接入 Rstest,用户无需再手动改测试配置。参考 在 Rsbuild 插件中修改 Rstest 配置。
    • project 级 silent。 多 project 配置里每个 project 可以单独设置 silent,只静音日志多的项目,其他项目的输出照常可见。参考 silent。
    • VS Code 扩展。 右键某个测试或文件选择「Run in Terminal」,即可在集成终端里以 rstest 命令运行它,看到完整的命令与原始输出;调试相关的新设置可以固定 inspector 端口、给 worker 传环境变量、调试时跳过 Node 内部代码。参考 VS Code 扩展。
    • --merge-reports 完整重放 reporter。 合并 blob 报告时按原始顺序重放全部 reporter hook,分片运行合并后的报告与单机运行一致,自定义 reporter 的统计不再遗漏。参考 rstest merge-reports。
    • browser mode 对齐 Node mode。 browser 项目现在也支持原生 V8 coverage、rs.mock、includeSource、globalSetup、Module Federation 与 watch 快捷键,用法与 Node mode 一致。参考 浏览器模式。

    升级至 Rstest 0.12

    把 @rstest/* 系列包升级到 0.12 即可。0.12 包含 JavaScript API 与部分 reporter 类型的不兼容变更;如果项目直接使用 @rstest/core/api 或自定义 reporter,建议升级前重点检查相关变更,详见全新的 JavaScript API与 Rstest instance。

    完整变更请参考 v0.12.0 release notes。