close

testEnvironment

  • 类型: 'node' | 'jsdom' | 'happy-dom' | string | { name: EnvironmentName, options?: EnvironmentOptions, target?: 'node' | 'web' }
  • 默认值: 'node'
  • CLI: --testEnvironment=node

测试时所使用的环境。

Rstest 默认使用 Node.js 作为测试环境。如果你在开发 Web 应用,可以使用类浏览器环境,如 jsdomhappy-dom

浏览器模式

如果你启用了 browser 模式,测试将直接在真实浏览器(Chromium/Firefox/WebKit)中运行。此时 testEnvironment 选项将失效,因为真实浏览器本身就是宿主环境。

CLI
rstest.config.ts
npx rstest --testEnvironment=jsdom

DOM 测试

Rstest 支持使用 jsdomhappy-dom 来模拟 DOM 和浏览器 API。

如果你想启用 DOM 测试,可以使用如下配置:

rstest.config.ts
import { defineConfig } from '@rstest/core';

export default defineConfig({
  testEnvironment: 'jsdom', // 或 'happy-dom'
});

你还需要安装对应的包:

使用 jsdom

npm
yarn
pnpm
bun
deno
npm add jsdom -D

使用 happy-dom

npm
yarn
pnpm
bun
deno
npm add happy-dom -D

启用 DOM 测试后,你可以在测试用例中使用 documentwindow 等浏览器 API。

test('DOM test', () => {
  document.body.innerHTML = '<p class="content">hello world</p>';
  const paragraph = document.querySelector('.content');
  expect(paragraph?.innerHTML).toBe('hello world');
});

环境选项

你也可以为测试环境传递选项。这对于配置 jsdomhappy-dom 非常有用。例如,你可以为 jsdom 设置 url

rstest.config.ts
import { defineConfig } from '@rstest/core';

export default defineConfig({
  testEnvironment: {
    name: 'jsdom',
    options: {
      // jsdom-specific options
      url: 'https://example.com',
    },
  },
});

options 对象会直接传递给环境的构造函数。

  • 对于 jsdom,它会传递给 JSDOM 构造函数。你可以在 jsdom 文档中找到可用的选项。
  • 对于 happy-dom,它会传递给 Window 构造函数。你可以在 happy-dom 文档中找到可用的选项。

自定义 environment

实验性 API

自定义 environment API 在 Rstest 1.0 之前仍处于实验阶段。它的核心形态预期会保持稳定,但类型签名和配置细节可能会根据迁移反馈做小幅调整。

Rstest 也支持通过 testEnvironment.name 加载自定义 environment。

  • 可以传包名。
  • 可以传相对或绝对 JavaScript 文件路径,例如 .js.mjs
  • 对于包名,testEnvironment: 'foo' 也会继续尝试解析 rstest-environment-foo

自定义 environment 需要默认导出一个 environment 对象。

my-environment.mjs
import { builtinEnvironments } from '@rstest/core';

/** @type {import('@rstest/core').TestEnvironment<typeof globalThis, { marker: string }>} */
const environment = {
  name: 'custom-jsdom',
  async setup(global, options) {
    const base = await builtinEnvironments.jsdom.setup(global, {
      url: 'https://example.com',
    });

    global.__MARKER__ = options.marker;

    return {
      async teardown() {
        delete global.__MARKER__;
        await base.teardown();
      },
    };
  },
};

export default environment;
rstest.config.ts
import { defineConfig } from '@rstest/core';

export default defineConfig({
  testEnvironment: {
    name: './my-environment.mjs',
    target: 'web',
    options: {
      marker: 'custom-marker',
    },
  },
});

@rstest/core 导出了 builtinEnvironments,这样你可以基于 nodejsdomhappy-dom 做扩展,而不是从零实现。

Rstest 当前会按 JavaScript module 加载自定义 environment 文件,因此暂不支持直接传 .ts custom environment 文件路径。如果你需要类型检查,可以先用 TypeScript 编写,再编译成 .mjs.js,或者在 JavaScript 文件里使用 JSDoc 标注类型。

target

  • 类型: 'node' | 'web'
  • 默认值: 'node'

target 用于控制自定义 environment 是否应该使用面向 Node.js 或面向 Web 的默认构建和解析行为。内置 environment 会自动推断该值,所以通常只有配置自定义 environment 时才需要使用这个选项。

使用 target: 'node' 时,自定义 environment 会使用与内置 node environment 相同的构建默认值。Rstest 会保留面向 Node 的解析默认值,并默认 externalize node_modules 中的第三方依赖。

使用 target: 'web' 时,自定义 environment 会使用内置 jsdomhappy-dom environment 共享的面向 Web 的构建默认值。在这个模式下,如果没有自定义 resolve.conditionNames,Rstest 会添加 browser condition 来解析面向浏览器的 package entry,并默认 bundle 第三方依赖,从而让 browser field 替换和被打包的资源生效。

rstest.config.ts
import { defineConfig } from '@rstest/core';

export default defineConfig({
  testEnvironment: {
    name: './my-environment.mjs',
    target: 'web',
    options: {
      url: 'https://example.com',
    },
  },
});

target 本身不会创建 DOM API,也不会启用 browser 模式。它只选择默认的构建和解析行为。environment 实现本身仍然需要负责安装 windowdocument 等全局对象。

如果你正在从 Jest 或 Vitest 迁移自定义 environment,请参考 从 Jest 迁移自定义 environment从 Vitest 迁移自定义 environment

对比自定义 environment 和 setupFiles

当你需要为每个测试文件定义或包装底层宿主环境本身时,用自定义 environment。

  • 切换或扩展 nodejsdomhappy-dom
  • 在测试模块执行前创建全局对象或宿主 API。
  • 管理 environment 级别的 teardown,例如关闭类浏览器运行时或清理注入的全局变量。

当环境本身已经正确,只需要在该环境里做测试初始化时,用 setupFiles

  • 注册 @testing-library/jest-dom 这类 matcher。
  • 安装 fake timers、snapshot serializer、mock 或通用 hooks。
  • 执行依赖当前 environment 已经准备好的项目级初始化逻辑。

一句话区分:testEnvironment 决定“测试运行在什么宿主里”;setupFiles 决定“测试在这个宿主里如何初始化”。

环境注释

你可以在测试文件顶部附近添加环境注释,为单个测试文件覆盖测试环境:

example.test.ts
// @rstest-environment jsdom

test('DOM test', () => {
  document.body.innerHTML = '<p>hello world</p>';
  expect(document.querySelector('p')?.textContent).toBe('hello world');
});

使用 @rstest-environment-options 可以为当前文件传递环境选项。选项必须是单行 JSON 对象:

example.test.ts
// @rstest-environment jsdom
// @rstest-environment-options { "url": "https://example.com/" }

test('sets the jsdom url', () => {
  expect(window.location.href).toBe('https://example.com/');
});

Rstest 也识别 @vitest-environment@jest-environment 别名,以及它们对应的 -options 变体,方便从 Vitest 或 Jest 迁移。

环境注释支持 Node runner 内置环境:nodejsdomhappy-dom。它不会应用到 browser mode。如果大多数文件使用同一个环境,建议优先在 rstest.config.ts 中配置 testEnvironment 或拆分 projects

示例