For AI agents: the complete documentation index is available at /zh/llms.txt, the full documentation bundle is available at /zh/llms-full.txt, and this page is available as Markdown at /zh/api/javascript-api/instance.md.
close
  • 简体中文
  • Rstest 实例

    本页介绍的所有 API 都由 @rstest/core@rstest/core/api 入口导出。你可以通过这些 API 创建 Rstest 实例、运行或列出测试、启动监听会话,以及合并 blob 报告。

    import { createRstest } from '@rstest/core/api';
    Warning

    目前所有导出都是实验性的,在 Rstest 1.0.0 之前可能发生变化。请暂时锁定 @rstest/core 的精确版本来保证 API 稳定性。

    createRstest

    createRstest 函数用于创建并返回一个 Rstest 实例。config 会在创建实例时解析一次,并作为实例的基础配置持续复用。传给实例方法的选项只应用于当前操作,不会修改这份基础配置。

    cwd 默认为 process.cwd(),并作为相对 config.root 的解析基准;省略 config 时使用空的内联配置,不会从 cwd 中发现配置文件。

    createRstest 会设置 RSTEST=true,仅当 NODE_ENV 尚未设置时才设置 NODE_ENV=test,并且不会恢复这两个环境变量。

    示例

    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);

    加载配置文件

    使用主入口的 loadConfig 加载配置文件,再将返回值({ content, filePath })直接作为 config 传入。

    import { loadConfig } from '@rstest/core';
    import { createRstest } from '@rstest/core/api';
    
    const loaded = await loadConfig();
    const rstest = await createRstest({ config: loaded });

    CreateRstestOptions

    • 类型:
    interface LoadedRstestConfig {
      content: RstestConfig; // 已加载的配置内容。
      filePath: string | null; // `loadConfig` 返回的配置文件来源路径,没有时为 `null`。
    }
    
    interface CreateRstestOptions {
      cwd?: string;
      config?: RstestConfig | LoadedRstestConfig;
      configLoader?: 'auto' | 'jiti' | 'native'; // 通过 `projects` 发现的配置文件所使用的 loader;默认为 `auto`。
    }
    
    function createRstest(options?: CreateRstestOptions): Promise<RstestInstance>;

    rstest.context

    rstest.context 是一个在创建实例时解析一次的只读对象。你可以在不运行测试的情况下检查解析后的状态,例如用 rootPath 确定结果中的 testPath 在 workspace 中的位置,用 projects 展示或筛选多项目配置,用 config 查看生效的配置,也可以用 version 做兼容性检查。

    示例

    import { createRstest } from '@rstest/core/api';
    
    const rstest = await createRstest({
      config: {
        projects: [
          {
            name: 'unit',
            include: ['tests/**/*.test.ts'],
          },
        ],
      },
    });
    
    console.log(rstest.context.version);
    console.log(rstest.context.rootPath);
    
    for (const project of rstest.context.projects) {
      console.log(project.name, project.rootPath);
    }

    RstestContext

    • 类型:
    interface ProjectContext {
      name: string; // 项目名称。
      rootPath: string; // 项目的绝对根路径。
      configFilePath?: string; // 与项目关联的配置文件路径(如果有)。
      configFileDependencies?: string[]; // 项目配置依赖,包括父级项目的配置文件。
    }
    
    interface RstestContext {
      readonly version: string;
      readonly rootPath: string;
      readonly config: Readonly<NormalizedConfig>;
      readonly projects: readonly ProjectContext[];
    }

    context.version

    当前使用的 @rstest/core 版本。

    • 类型: string

    context.rootPath

    Rstest 实例的绝对根路径。它由 config.root 解析得出;当 config.root 为相对路径时,以 cwd 为基准。

    • 类型: string

    context.config

    Rstest 实例规范化后的配置。

    • 类型: Readonly<NormalizedConfig>

    context.projects

    解析后的项目 Context。未显式配置 projects 时,该数组包含由 config.name 命名的默认项目(默认名称为 'rstest')。

    • 类型: readonly ProjectContext[]

    rstest.run

    rstest.run() 会运行一个测试轮次,并返回 TestRunResult。当无效选项、配置或 compiler 错误导致运行无法启动时,Promise 会被拒绝;测试失败仍通过 status 报告,不会导致 Promise 被拒绝,具体规则见 TestRunResult

    示例

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

    RunOptions

    RunOptions 接受除 configconfigLoaderroottrace 之外的所有 rstest run flag。完整 flag 列表见 CLI 选项,精确类型见 packages/core/src/api/types.ts

    filters 仅用于 API;CLI 通过位置参数传入 filter。它默认使用不区分大小写的子字符串匹配。用成对的单引号或双引号包裹 filter,可精确匹配绝对路径或相对于 root 的路径,例如 filters: ['"src/foo.test.ts"', 'utils'];带引号和不带引号的 filter 可以混用。省略 filters 时选择所有文件;显式传入空数组时不会选择任何文件。

    • 类型:
    interface RunOptions {
      filters?: string[];
      // ……以及其余所有 `rstest run` flag,用于覆盖同名配置项,
      // 例如 `testTimeout`、`coverage`、`reporters`。
    }
    
    interface RstestInstance {
      run(options?: RunOptions): Promise<TestRunResult>;
    }

    TestRunResult

    • 类型:
    type TestRunStatus = 'pass' | 'fail' | 'error';
    
    interface TestRunResult {
      status: TestRunStatus; // 本次运行的整体状态。
      // 其余字段与 `onTestRunEnd` 的 payload 相同,去掉 `getSourcemap`。
    }

    其余字段(resultstestResultssummarydurationsnapshotSummaryunhandledErrorscoveragererunTestPaths)的说明见 Reporter API 的 onTestRunEnd

    unhandledErrors 不为空时,status'error'。当本次运行已完成但退出状态非零时,status'fail',例如测试或测试文件失败、覆盖率未达阈值、未设置 passWithNoTests 时没有找到测试,或者 globalSetup 清理失败。watch 模式下,只要会话里还有失败的测试文件,即使当前轮次全部通过,status 仍是 'fail'。其他情况下,status'pass'

    unhandledErrors 里的每一项都是普通对象,可以直接序列化为 JSON,不是 Error 实例。

    rstest.watch

    rstest.watch() 会启动监听会话,并返回用于关闭它的监听器。

    示例

    import { createRstest } from '@rstest/core/api';
    
    const rstest = await createRstest({
      config: {
        include: ['src/**/*.test.ts'],
      },
    });
    
    const watcher = await rstest.watch({
      onResult(result) {
        console.log(
          result.status,
          result.results.map((file) => file.testPath),
          result.rerunTestPaths,
        );
      },
    });
    
    await watcher.close();

    每一轮结束后都会调用 onResult,第一轮也不例外。resultssummarystatus 反映整个 watch 会话的状态,rerunTestPaths 是这一轮实际执行的文件。

    支持浏览器项目。重跑执行出错会通过 onResultstatus: 'error' 交付,不会关闭会话;启动失败(包括浏览器 globalSetup 失败)会使 watch() 被拒绝。

    onResult 抛出的错误会被隔离,不会停止监听会话。调用 watcher.close() 会释放编译器、worker、文件监听器,并运行待处理的 globalSetup 清理函数。该方法是幂等的,重复调用会得到相同结果;清理失败时,它返回的 Promise 会被拒绝。

    rstest.watch() 会拒绝 relatedchanged,因为它们会选择固定的文件集合,而监听会话必须能够发现新的关联测试。使用这些选项时请调用 rstest.run()related: falsechanged: false 会被忽略。

    WatchOptions

    • 类型:
    interface WatchOptions {
      onResult?: (result: TestRunResult & { rerunTestPaths: string[] }) => void;
    }
    
    interface RstestWatcher {
      close(): Promise<void>;
    }
    
    interface RstestInstance {
      watch(options?: WatchOptions & RunOptions): Promise<RstestWatcher>;
    }

    rstest.listTests

    rstest.listTests() 会收集测试文件和测试声明,但不运行测试主体。

    示例

    import { createRstest } from '@rstest/core/api';
    
    const rstest = await createRstest({
      config: {
        include: ['src/**/*.test.ts'],
      },
    });
    
    const tests = await rstest.listTests({
      includeSuites: true,
      includeTaskLocation: true,
    });
    
    console.log(tests);

    设置 filesOnly 可跳过声明收集。includeSuites 会将具名测试套件作为独立条目返回。RunOptions 中的 includeTaskLocation 会加入源码位置。

    每个条目都包含 testPathproject。隐式默认项目的条目使用 config.name(默认为 'rstest')。测试声明条目包含自身的 name、带测试套件前缀的 fullName,以及表示层级的 parentNames;文件条目不包含 namefullName。标记为 skiptodo 的声明也会返回,runMode 分别为 skiptodo;可运行声明不提供 runMode

    条目按深度优先的声明顺序返回。测试套件紧邻其后代之前,同一文件的所有条目保持连续。

    收集失败时,rstest.listTests() 返回的 Promise 会以 ListTestsError 拒绝,而不是返回部分列表或空列表。

    只有显式传给 rstest.listTests()shard 才会生效,并将结果限制在选定分片。省略 shard 时会列出所有文件;实例配置中的 shard 仍会像以前一样被丢弃。

    ListOptions

    • 类型:
    interface ListOptions {
      filesOnly?: boolean;
      includeSuites?: boolean;
    }
    
    interface ListedTest {
      testPath: string; // 测试文件路径。
      name?: string; // 声明自身的名称;文件条目不包含此字段。
      fullName?: string; // 带测试套件前缀的显示名称;文件条目不包含此字段。
      parentNames?: string[]; // 外层测试套件的名称。
      project: string; // 项目名称。
      location?: TestLocation; // 请求后提供的源码位置。
      runMode?: 'skip' | 'todo'; // 不可运行声明的 skip 或 todo 模式。
      type: 'file' | 'suite' | 'case'; // 条目类型。
    }
    
    interface RstestInstance {
      listTests(options?: ListOptions & RunOptions): Promise<ListedTest[]>;
    }

    rstest.mergeReports

    rstest.mergeReports() 用于合并 blob 报告,并返回与 rstest.run() 相同的结果模型。

    当本次操作无法产生运行结果时,Promise 会被拒绝;合并的测试结果中若有测试失败,仍通过 status 报告,不会导致 Promise 被拒绝。

    示例

    import { createRstest } from '@rstest/core/api';
    
    const rstest = await createRstest();
    
    const result = await rstest.mergeReports({
      path: './.rstest-reports',
      cleanup: true,
    });
    
    console.log(result.status);

    path 用于选择 blob 报告目录。cleanup 会在合并成功后删除已消费的报告。

    MergeReportsOptions

    • 类型:
    interface MergeReportsOptions {
      path?: string;
      cleanup?: boolean;
    }
    
    interface RstestInstance {
      mergeReports(options?: MergeReportsOptions): Promise<TestRunResult>;
    }

    runCLI

    runCLI 会在当前进程中运行 Rstest 命令行。它会解析 argv、设置 process.exitCode,并安装 CLI 的 signal handlers。需要 CLI 的进程行为时,请使用 runCLI;实例方法不会设置 process.exitCode 或安装 signal handlers。

    示例

    import { runCLI } from '@rstest/core/api';
    
    runCLI({
      argv: [...process.argv.slice(0, 2), 'run', 'src/foo.test.ts', '--update'],
    });

    argv 的结构与 Node.js 的 process.argv 一致,默认值为 process.argv:前两项是 executable 和 script 的路径,会被忽略,命令、filters 和 flags 从索引 2 开始。 这与 Rsbuild 和 Rspress 的 runCLI 使用的结构相同。

    所有可用的命令和选项,请参阅 CLI 文档

    RunCLIOptions

    • 类型:
    interface RunCLIOptions {
      argv?: string[];
    }
    
    function runCLI(options?: RunCLIOptions): void;