Skip to content
Vitest 2
Main Navigation 指南API配置浏览器模式高级
2.1.9
1.6.1
0.34.6

简体中文

English
繁體中文
Español
Français
Русский
Português – Brasil
Deutsch
日本語
한국어
Italiano
Polski
Türkçe
čeština
magyar

简体中文

English
繁體中文
Español
Français
Русский
Português – Brasil
Deutsch
日本語
한국어
Italiano
Polski
Türkçe
čeština
magyar

主题

Sidebar Navigation

Node API

测试运行器

任务元数据

扩展报告器

自定义 pool

页面导航

扩展报告器 ​

你可以从 vitest/reporters 导入报告器,并通过扩展它们来创建自定义报告器。

扩展内置报告器 ​

通常,你不需要从头开始创建报告器。vitest 默认提供了一些报告器,你可以扩展它们。

ts
import { DefaultReporter } from 'vitest/reporters';

export default class MyDefaultReporter extends DefaultReporter {
  // 执行某些操作
}

当然,你也可以从零开始创建报告器。只需扩展 BaseReporter 类并实现所需的方法。

下面是一个自定义报告器的示例:

ts
// ./custom-reporter.js
import { BaseReporter } from 'vitest/reporters';

export default class CustomReporter extends BaseReporter {
  onCollected() {
    const files = this.ctx.state.getFiles(this.watchFilters);
    this.reportTestSummary(files);
  }
}

或者实现 Reporter 接口:

ts
// ./custom-reporter.js
import { Reporter } from 'vitest/reporters';

export default class CustomReporter implements Reporter {
  onCollected() {
    // 输出内容
  }
}

然后你可以在 vitest.config.ts 文件中使用你的自定义报告器:

ts
import { defineConfig } from 'vitest/config';
import CustomReporter from './custom-reporter.js';

export default defineConfig({
  test: {
    reporters: [new CustomReporter()],
  },
});

已报告的任务 ​

WARNING

这是一个实验性 API。可能会有不遵循 SemVer 的重大更改。使用时请固定 Vitest 的版本。

你可以通过调用 vitest.state.getReportedEntity(runnerTask) 来访问此 API:

ts
import type { Vitest } from 'vitest/node';
import type { RunnerTestFile } from 'vitest';
import type { Reporter, TestModule } from 'vitest/reporters';

class MyReporter implements Reporter {
  ctx!: Vitest;

  onInit(ctx: Vitest) {
    this.ctx = ctx;
  }

  onFinished(files: RunnerTestFile[]) {
    for (const fileTask of files) {
      // 请注意,旧的任务实现使用的是 'file' 而非 'module'
      const testModule = this.ctx.state.getReportedEntity(
        fileTask
      ) as TestModule;
      for (const task of testModule.children) {
        //                          ^?
        console.log('finished', task.type, task.fullName);
      }
    }
  }
}

我们计划在 Vitest 2.1 中使该 API 稳定。

TestCase ​

TestCase 代表一个单独的测试用例。

ts
declare class TestCase {
  readonly type = 'test' | 'custom';
  /**
   * 任务实例。
   * @experimental 公共任务 API 是实验性的,不遵循 semver。
   */
  readonly task: RunnerTestCase | RunnerCustomCase;
  /**
   * 与测试相关的项目。
   */
  readonly project: TestProject;
  /**
   * 直接引用定义测试的测试模块。
   */
  readonly module: TestModule;
  /**
   * 测试的名称。
   */
  readonly name: string;
  /**
   * 测试的完整名称,包含所有父级套件,以 `>` 分隔。
   */
  readonly fullName: string;
  /**
   * 唯一标识符。
   * 此 ID 是确定性的,在多次运行中对于同一个测试将保持不变。
   * ID 基于项目名称、模块 ID 和测试位置。
   */
  readonly id: string;
  /**
   * 定义测试的模块中的位置。
   * 只有在配置中启用了 `includeTaskLocation` 才会收集位置信息。
   */
  readonly location: { line: number; column: number } | undefined;
  /**
   * 父套件。如果测试是在模块内部直接调用的,则父级将是该模块本身。
   */
  readonly parent: TestSuite | TestModule;
  /**
   * 初始化测试时所用的选项。
   */
  readonly options: TaskOptions;
  /**
   * 检查测试是否通过(未导致套件失败)。
   * 如果测试尚未完成或被跳过,则返回 `true`。
   */
  ok(): boolean;
  /**
   * 在测试执行期间附加的自定义元数据。
   */
  meta(): TaskMeta;
  /**
   * 测试结果。如果测试尚未完成或刚被收集,则值为 `undefined`。
   */
  result(): TestResult | undefined;
  /**
   * 关于测试的有用信息,如持续时间、内存使用等。
   */
  diagnostic(): TestDiagnostic | undefined;
}

export type TestResult =
  | TestResultPassed
  | TestResultFailed
  | TestResultSkipped;

export interface TestResultPassed {
  /**
   * 测试成功。
   */
  state: 'passed';
  /**
   * 测试执行期间抛出的错误。
   *
   * **注意**:即使测试成功重试,错误信息仍然会被报告。
   */
  errors: TestError[] | undefined;
}

export interface TestResultFailed {
  /**
   * 测试执行失败。
   */
  state: 'failed';
  /**
   * 测试执行期间抛出的错误。
   */
  errors: TestError[];
}

export interface TestResultSkipped {
  /**
   * 测试被标记为 `only`、`skip` 或 `todo` 而跳过。
   * 你可以在 `mode` 选项中查看使用了哪个跳过标志。
   */
  state: 'skipped';
  /**
   * 跳过的测试不会有错误。
   */
  errors: undefined;
}

export interface TestDiagnostic {
  /**
   * 如果测试的持续时间超过 `slowTestThreshold`。
   */
  slow: boolean;
  /**
   * 测试所使用的内存量(字节)。
   * 此值仅在测试使用 `logHeapUsage` 标志执行时可用。
   */
  heap: number | undefined;
  /**
   * 执行测试所需的时间(毫秒)。
   */
  duration: number;
  /**
   * 测试开始的时间(毫秒)。
   */
  startTime: number;
  /**
   * 测试重试的次数。
   */
  retryCount: number;
  /**
   * 按照 `repeats` 选项配置的测试重复次数。
   * 如果测试在重复期间失败且未配置 `retry`,则此值可能较低。
   */
  repeatCount: number;
  /**
   * 如果测试在第二次重试时通过。
   */
  flaky: boolean;
}

TestSuite ​

TestSuite 代表一个包含测试和其他套件的测试套件。

ts
declare class TestSuite {
  readonly type = 'suite';
  /**
   * 任务实例。
   * @experimental 公共任务 API 是实验性的,不遵循 semver。
   */
  readonly task: RunnerTestSuite;
  /**
   * 与测试相关的项目。
   */
  readonly project: TestProject;
  /**
   * 直接引用定义套件的测试模块。
   */
  readonly module: TestModule;
  /**
   * 套件的名称。
   */
  readonly name: string;
  /**
   * 套件的完整名称,包含所有父级套件,以 `>` 分隔。
   */
  readonly fullName: string;
  /**
   * 唯一标识符。
   * 此 ID 是确定性的,在多次运行中对于同一个测试将保持不变。
   * ID 基于项目名称、模块 ID 和测试位置。
   */
  readonly id: string;
  /**
   * 定义套件的模块中的位置。
   * 只有在配置中启用了 `includeTaskLocation` 才会收集位置信息。
   */
  readonly location: { line: number; column: number } | undefined;
  /**
   * 此套件包含的子套件和测试的集合。
   */
  readonly children: TaskCollection;
  /**
   * 初始化套件时使用的选项。
   */
  readonly options: TaskOptions;
}

TestModule ​

TestModule 代表一个包含套件和测试的单独文件(测试模块)。

ts
declare class TestModule extends SuiteImplementation {
  readonly type = 'module';
  /**
   * 任务实例。
   * @experimental 公共任务 API 是实验性的,不遵循 semver。
   */
  readonly task: RunnerTestFile;
  /**
   * 该模块中包含的套件和测试的集合。
   */
  readonly children: TestCollection;
  /**
   * 这通常是一个绝对的 Unix 文件路径。
   * 如果文件不在磁盘上,它可能是一个虚拟 ID。
   * 此值对应于 Vite 的 `ModuleGraph` ID。
   */
  readonly moduleId: string;
  /**
   * 关于模块的有用信息,如持续时间、内存使用等。
   * 如果模块尚未执行,所有诊断值将返回 `0`。
   */
  diagnostic(): ModuleDiagnostic;
}

export interface ModuleDiagnostic {
  /**
   * 导入和初始化环境所需的时间。
   */
  environmentSetupDuration: number;
  /**
   * Vitest 设置测试工具(runner、mocks 等)所需的时间。
   */
  prepareDuration: number;
  /**
   * 导入测试模块所需的时间。
   * 这包括导入模块中的所有内容并执行套件回调。
   */
  collectDuration: number;
  /**
   * 导入 setup 模块所需的时间。
   */
  setupDuration: number;
  /**
   * 模块中所有测试和钩子的累积持续时间。
   */
  duration: number;
}

TestCollection ​

TestCollection 代表套件和测试的集合。它还提供了一些有用的方法来遍历集合中的元素。

ts
declare class TestCollection {
  /**
   * 返回数组中特定索引处的测试或套件。
   */
  at(index: number): TestCase | TestSuite | undefined;
  /**
   * 集合中测试和套件的数量。
   */
  size: number;
  /**
   * 以数组形式返回集合,便于操作。
   */
  array(): (TestCase | TestSuite)[];
  /**
   * 过滤此集合及其子集合中的所有套件。
   */
  allSuites(): IterableIterator<TestSuite>;
  /**
   * 过滤此集合及其子集合中的所有测试。
   */
  allTests(state?: TestResult['state'] | 'running'): IterableIterator<TestCase>;
  /**
   * 仅过滤属于此集合的测试。
   */
  tests(state?: TestResult['state'] | 'running'): IterableIterator<TestCase>;
  /**
   * 仅过滤属于此集合的套件。
   */
  suites(): IterableIterator<TestSuite>;
  [Symbol.iterator](): IterableIterator<TestSuite | TestCase>;
}

例如,你可以通过调用 testModule.children.allTests() 来遍历模块内的所有测试:

ts
function onFileCollected(testModule: TestModule): void {
  console.log('collecting tests in', testModule.moduleId);

  // 遍历模块内的所有测试和套件
  for (const task of testModule.children.allTests()) {
    console.log('collected', task.type, task.fullName);
  }
}

TestProject ​

TestProject 是与模块关联的项目。该模块内的每个测试和套件都将引用同一个项目。

通过项目,可以方便地获取配置信息或访问提供的上下文。

ts
declare class TestProject {
  /**
   * 全局 vitest 实例。
   * @experimental 公共 Vitest API 是实验性的,不遵循 semver。
   */
  readonly vitest: Vitest;
  /**
   * 与该测试项目相关联的工作区项目。
   * @experimental 公共 Vitest API 是实验性的,不遵循 semver。
   */
  readonly workspaceProject: WorkspaceProject;
  /**
   * Vite 的开发服务器实例。每个工作区项目都有自己的服务器。
   */
  readonly vite: ViteDevServer;
  /**
   * 已解析的项目配置。
   */
  readonly config: ResolvedProjectConfig;
  /**
   * 已解析的全局配置。如果没有工作区项目,这将与 `config` 相同。
   */
  readonly globalConfig: ResolvedConfig;
  /**
   * 序列化的项目配置,即测试所接收的配置。
   */
  get serializedConfig(): SerializedConfig;
  /**
   * 项目的名称,如果未设置则为空字符串。
   */
  name(): string;
  /**
   * 提供给项目的自定义上下文。
   */
  context(): ProvidedContext;
  /**
   * 为项目提供自定义的可序列化上下文。此上下文在测试运行时可用。
   */
  provide<T extends keyof ProvidedContext & string>(
    key: T,
    value: ProvidedContext[T]
  ): void;
}

导出的报告器 ​

vitest 提供了一些可以直接使用的内置报告器。

内置报告器: ​

  1. BasicReporter
  2. DefaultReporter
  3. DotReporter
  4. JsonReporter
  5. VerboseReporter
  6. TapReporter
  7. JUnitReporter
  8. TapFlatReporter
  9. HangingProcessReporter

基础抽象报告器: ​

  1. BaseReporter

接口报告器: ​

  1. Reporter
Pager
上一页任务元数据
下一页自定义 pool

基于 MIT 许可证 发布。

版权所有 (c) 2024 Mithril Contributors

https://v2.vitest.dev/advanced/reporters

基于 MIT 许可证 发布。

版权所有 (c) 2024 Mithril Contributors