close

适配器

适配器是一个强大的功能,它允许你将来自其他工具(如构建工具或 CLI)的配置转换为 Rstest 支持的配置格式。通过创建一个自定义适配器,你可以复用现有配置,避免在多个工具之间重复定义,并确保项目的一致性。

本指南将引导你完成创建和使用自定义 Rstest 适配器的过程。

为什么使用适配器

  • 复用配置: 将已有的构建工具配置(如路径别名、全局变量等)转换为测试配置,避免重复定义。
  • 框架定制: 允许框架或模板预设测试配置,例如添加特定的 setup 脚本、更改默认超时时间或设置默认测试环境,从而提供开箱即用的测试体验。
  • 简化维护: 集中管理配置,减少手动同步不同工具配置的麻烦,降低出错可能性。
  • 快速集成: 通过适配器,可以快速将 Rstest 集成到现有项目中,复用已有的项目配置。

核心概念

Rstest 的配置扩展功能主要依赖 extends 选项。此选项可以接受一个对象或一个函数 (ExtendConfigFn),该函数返回一个配置对象 (ExtendConfig) 或一个解析为该对象的 Promise。

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

export default defineConfig({
  // `extends` 可以是一个对象、一个 Promise 或一个函数
  extends: async () => {
    // 动态返回配置
    return {
      testTimeout: 5000,
    };
  },
});

适配器的本质就是一个实现了 ExtendConfigFn 接口的函数。

// 来自 @rstest/core/types/config.ts
export type ExtendConfig = Omit<RstestConfig, 'projects'>;

export type ExtendConfigFn = (
  userConfig: Readonly<RstestConfig>,
) => MaybePromise<ExtendConfig>;

适配器函数接收用户当前的 Rstest 配置作为参数,并返回一个新的配置对象,该对象将与用户配置进行深度合并。

创建一个自定义适配器

创建一个自定义适配器包含以下步骤:

  1. 定义一个适配器函数: 此函数应符合 ExtendConfigFn 类型签名。
  2. 加载外部配置: 在函数内部,读取并解析你想要集成的工具的配置文件(例如 my-build-tool.config.js)。
  3. 转换配置: 将加载的配置映射到 ExtendConfig 接口定义的字段。这是适配器的核心逻辑,你需要决定如何将源配置的属性(如 aliasdefine 等)转换为 Rstest 的相应选项(如 resolve.aliassource.define)。
  4. 返回配置: 返回转换后的 ExtendConfig 对象。

示例:一个简单的适配器

假设你有一个自定义的构建配置文件 my.config.ts,内容如下:

// my.config.ts
export default {
  base: '/src',
  aliases: {
    '@': './utils',
  },
  globals: {
    __VERSION__: '1.0.0',
  },
};

你可以创建一个适配器 my-adapter.ts 来读取此文件并将其转换为 Rstest 配置。

// my-adapter.ts
import { type ExtendConfigFn } from '@rstest/core';
import myConfig from './my.config'; // 导入你的配置

export const withMyConfig: ExtendConfigFn = async (userConfig) => {
  // 1. 读取配置 (已通过 import 完成)

  // 2. 转换配置
  const rstestConfig = {
    root: myConfig.base, // `base` 映射到 `root`
    resolve: {
      alias: myConfig.aliases, // `aliases` 映射到 `resolve.alias`
    },
    source: {
      define: myConfig.globals, // `globals` 映射到 `source.define`
    },
  };

  // 3. 返回转换后的配置
  return rstestConfig;
};

使用你的自定义适配器

现在,你可以在 Rstest 配置文件中使用你创建的适配器:

// rstest.config.ts
import { defineConfig } from '@rstest/core';
import { withMyConfig } from './my-adapter';

export default defineConfig({
  extends: withMyConfig,
  // 在这里可以继续添加或覆盖其他 Rstest 特定配置
  testTimeout: 8000,
});

当 Rstest 加载此配置时,它将:

  1. 调用 withMyConfig 函数。
  2. 获取返回的配置对象。
  3. 将其与 defineConfig 中的内联配置深度合并。需要注意的是,用户的本地配置(如 testTimeout: 8000)将优先于 extends 返回的配置。

高级用法:带选项的适配器

@rstest/adapter-rslib 类似,你可以让你的适配器接受一个选项对象,以实现更灵活的集成。

// my-adapter.ts
import { type ExtendConfigFn } from '@rstest/core';
import { load } from './loader'; // 假设有一个加载器

export interface MyAdapterOptions {
  configPath?: string;
  profile?: 'web' | 'node';
}

export function withMyConfig(options: MyAdapterOptions = {}): ExtendConfigFn {
  return async (userConfig) => {
    const config = await load(options.configPath); // 从指定路径加载

    const rstestConfig = {
      // ...转换逻辑
      testEnvironment: options.profile === 'web' ? 'happy-dom' : 'node',
    };

    return rstestConfig;
  };
}

使用方式如下:

// rstest.config.ts
import { defineConfig } from '@rstest/core';
import { withMyConfig } from './my-adapter';

export default defineConfig({
  extends: withMyConfig({ profile: 'web' }),
});

通过这种方式,你可以创建功能强大且可复用的适配器,将任何工具链与 Rstest 无缝集成。

使用官方适配器

以下是 Rstest 官方支持的适配器:

  • Rslib Adapter:用于从 Rslib 配置中扩展 Rstest 配置。