e2e配置指南:e2e.config.ts 每个字段都讲明白
【免费下载链接】e2eNext generation e2e testing framework for web and mobile apps.项目地址: https://gitcode.com/GitHub_Trending/e2e6/e2e
e2e 是一个面向 Web 和移动应用的下一代端到端(e2e)测试框架:用自然语言描述目标,AI Agent 就会驱动应用去达成,再用定位器和断言检查结果。而所有这一切的起点,就是项目根目录里的e2e.config.ts配置文件。本文将把这个 e2e 配置文件里的每个字段——targets、tests、timeout、trace、agents、cache、secrets等——逐个讲明白,并给出每个字段的默认值,帮你快速写出第一份可用的配置。
如何找到和加载你的 e2e.config.ts 配置
在讲字段之前,先搞清楚三件小事:
- 文件名:
e2e.config.ts或e2e.config.mts,也可以直接用e2e run --config <path>指定; - 查找规则:运行器从工作目录逐级向上查找,直到仓库根目录。选中文件所在的目录就是项目根目录;同一目录里两个名字都存在会报
CONFIG_AMBIGUOUS; - 严格校验:任何不认识的键都会被拒绝并报错
INVALID_CONFIG,所有数值必须是安全整数。可选字段要么给值、要么整个省略(不允许显式写undefined)。
一个最小可用的 e2e 配置长这样(完整示例见 examples/with-next/e2e.config.ts):
import type { E2EConfig } from 'e2e'; import { web } from '@e2e-dev/web'; export default { targets: [ { engine: web(), app: { url: 'http://localhost:3100' } }, ], } satisfies E2EConfig;下面这张「字段速查表」列出了顶层全部字段及默认值(完整参考:docs/reference/config.mdx):
| 字段 | 必填 | 默认值 | 一句话说明 |
|---|---|---|---|
targets | ✅ | 无,至少 1 个 | 测试目标:引擎 + 被测应用 |
tests | ❌ | tests/**/*.e2e.ts | 测试文件的 glob,!开头为排除 |
timeout | ❌ | 120000 ms | 单个测试的总时限 |
launchTimeout | ❌ | 60000 ms | 引擎初始化与启动预算 |
actionTimeout | ❌ | 30000 ms | 每个引擎操作的预算 |
assertionTimeout | ❌ | 5000 ms | expect断言的默认等待 |
cleanupTimeout | ❌ | 30000 ms | 清理钩子与引擎收尾预算 |
retries | ❌ | 本地 0 / CI 1 | 每个测试的重试次数(0–10) |
workers | ❌ | 本地 CPU 核数一半 / CI 1 | 并行 worker 数(1–1024) |
trace/video | ❌ | on/off | 录制模式,详见下文 |
output | ❌ | .e2e | 报告与产物输出目录 |
reporters | ❌ | list | 报告输出器:junit、markdown、json等 |
agents | ❌ | 无 | 具名 AI Agent 配置 |
cache | ❌ | 本地读-写 / CI 只读 | Agent 操作回放缓存 |
credentials/secrets | ❌ | 无 | 测试账号与密钥(自动脱敏) |
projectId | ❌ | 根package.json的 name | 稳定的项目标识 |
artifacts | ❌ | 仅本地 | 把产物推送到远端存储 |
failOnSkippedFailure | ❌ | false | 失败后跳过是否让整个运行失败 |
targets:每个 e2e 测试目标讲明白
targets是 e2e 配置的核心——每个 target 由三部分构成:name(报告里的名字,--target参数也用它)、engine(驱动应用的方式:web(...)、mobile(...)或自定义引擎)、app(被测应用本身)。
targets: [ { name: 'web', engine: web({ viewport: { width: 1440, height: 900 } }), app: { url: 'http://localhost:3000', command: { executable: 'npm', args: ['run', 'dev'] }, readyUrl: 'http://localhost:3000/health', }, }, ],app:被测应用字段速查
| 键 | 适用 | 作用 |
|---|---|---|
url | web | 基础 URL,app.open()从它开始 |
bundleId | mobile | 设备上已安装应用的标识 |
appPath | mobile | 要安装的.app/.apk构建产物 |
identity | 通用 | 回放缓存的稳定身份键(默认取 URL 的 origin + 路径) |
environment | 通用 | test/staging/production标签 |
launchArguments/permissions | mobile | 每次冷启动的参数与权限设置 |
command | 通用 | 测试前自动拉起的进程(如 dev server) |
readyUrl | 通用 | 轮询此 URL 直到 200–499,判定command就绪 |
几个新手常踩的点:
web()target 必须有app.url,且不能出现bundleId、appPath等移动端键,反之亦然,混用直接INVALID_CONFIG;command支持{port}占位符。把url写成http://127.0.0.1:0可让运行器自动分配空闲端口,command.args里的{port}会被替换成实际端口;- 多个 target 声明同一个
command时共享一个进程;reuseExisting: true时,如果端口上已有服务在跑就直接复用(CI 中会被忽略)。
engine的选项则管的是"怎么驱动":web({ browser, viewport, headers, basicAuth, userAgent, locale, timezoneId, ... })见 docs/reference/web.mdx;mobile({ platform, device, session, transition })见 docs/reference/mobile.mdx。
下面的 Next.js 示例应用就是被app.url指向、由测试驱动的目标页面:
tests、超时与并行:控制测试如何运行
export default { tests: ['tests/**/*.e2e.ts', '!tests/wip/**'], timeout: 120_000, // 单个测试的总时限 assertionTimeout: 5_000, // expect 默认等待 retries: 1, // 本地跑也想重试就显式写 workers: 4, // 并行 worker 数 } satisfies E2EConfig;tests是相对项目根的 glob 列表,!开头的条目做排除(排除项与顺序无关);只写排除项是不合法的;- 四个超时字段分工很清晰:
timeout管整个测试,launchTimeout管引擎启动,actionTimeout管单次操作,assertionTimeout管断言轮询,cleanupTimeout管收尾; retries和workers的默认值会随 CI 环境自动切换:本地retries: 0、CIretries: 1;本地 worker 取核数一半、CI 强制为 1。
trace 与 video:e2e 录制模式怎么选
trace(操作轨迹)和video(录屏)共用同一组 5 种RecordingMode,取值从小到大:
| 模式 | 录什么 | 保留什么 |
|---|---|---|
off | 不录 | 无 |
on | 每次尝试 | 全部 |
retain-on-failure | 每次尝试 | 仅失败尝试的 |
on-first-retry | 仅第一次重试 | 该次录制 |
on-all-retries | 首次之后的每次 | 全部录制 |
默认值:本地trace: 'on'、CItrace: 'on-first-retry'(全量 trace 会让运行时间增加约四分之一,CI 默认只录重试那次很合理);video默认一律off,因为视频最贵且会原样记录屏幕上的敏感内容。
优先级从低到高是:配置文件顶层 → target 上的trace/video→ 命令行--trace/--video→ 单个测试自己的选项。
export default { trace: 'on-first-retry', video: 'retain-on-failure', targets: [ { engine: web(), app: { url: 'http://localhost:3000' } }, { name: 'firefox', engine: web({ browser: 'firefox' }), app: { url: 'http://localhost:3000' }, video: 'on' }, ], } satisfies E2EConfig;output 与 reporters:e2e 测试报告去哪了
一次运行写的所有东西都收在output目录(默认.e2e)下:report.json(规范报告,--last-failed读它)、junit.xml/summary.md(对应报告器)、artifacts/(截图、trace、视频、下载文件,每次运行的最新证据)等。改了output记得把它加进.gitignore。
reporters可以叠加输出器,内置的有'list'、'junit'、'markdown'、'json',还能加自定义报告器对象。官方仓库自己的 Web 基准套件(apps/web-benchmark/e2e.config.ts)就是这样把结果发到 Pull Request 评论的:
reporters: ['list', github({ key: 'web' })], // 来自 @e2e-dev/github移动端基准套件(apps/mobile-benchmark/e2e.config.ts)则展示了多 target 写法:iOS 模拟器 + Android 模拟器各一个 target,workers跟随设备池数量。
cache、credentials 与 secrets:缓存和密钥字段
cache(回放缓存)——Agent 执行过的操作在后续断言通过后才被记录,下次运行直接回放、零模型调用。三个模式:read-write(本地默认)、read-only(CI 默认)、off。可选配置项:
cache: { mode: 'read-only', dir: '.e2e/cache', // 默认位置;e2e init 会把它写入 .gitignore,想共享回放就删掉那行 strict: true, // 录制已失效时以 REPLAY_STALE 失败,而不是交还给 Agent },credentials / secrets——写进配置的账号密码和 API 密钥,运行器会自动在截图、日志、trace、报告中脱敏成<secret:name>:
credentials: { admin: { username: 'admin@tester.army', password: 'at-least-6-chars' }, }, secrets: { previewPassword: process.env.PREVIEW_PASSWORD, // 也支持 () => string 的供应商函数 },之后用credentials.user('admin').password或secrets.get('previewPassword')拿到不透明句柄,直接传给locator.fill即可,测试代码永远读不到明文。环境变量的E2E_USER_<NAME>_USERNAME/_PASSWORD和E2E_SECRET_<NAME>优先级高于配置值。
agents 配置:给 e2e AI 测试接上大脑
只有用到agentfixture 的测试才需要这一节。agents是一个具名映射,测试默认使用default:
agents: { default: { model: gateway('openai/gpt-6-luna-fast'), // 任意 AI SDK 模型实例 system: 'You are a thorough QA agent. Verify every outcome.', context: 'Plans are called tiers. Billing lives under Settings.', }, buyer: { model: gateway('openai/gpt-6-luna-fast'), system: 'You are a first-time buyer.', maxSteps: 40, }, } satisfies E2EConfig;常用子项:model(驱动 Agent 的模型实例,必填,无隐式默认)、judge(断言/等待/抽取用的模型,默认同model)、context(告诉模型"这个应用把东西叫什么")、maxSteps与maxModelCalls(每次调用的动作与请求上限,默认 25)、judgmentTimeout(默认 30000 ms)。注意:Agent 之间不互相继承,每个条目都从内置默认值起步。也可以用executor字段换上自定义大脑。
CI 与本地默认值对照表
最后用一张表总结"不写也会生效"的环境差异(CI 由CI环境变量判定):
| 设置 | 本地 | CI |
|---|---|---|
retries | 0 | 1 |
workers | 核数的一半 | 1 |
cache(未显式设置时) | read-write | read-only |
trace | on | on-first-retry |
test.only | 允许 | 报错ONLY_IN_CI |
command.reuseExisting | 生效 | 忽略,总是新起进程 |
写在最后
记住这份 e2e 配置指南的心法其实很简单:targets里的engine管"怎么驱动"、app管"测什么",其余字段都是围绕超时、并行、录制、报告、缓存、密钥的开关;所有未知键都会让配置加载失败并给出最接近的正确拼写提示,写错了跑不起来反而省心。
想动手试试,最快的路径是npx e2e init,或直接对照仓库里四个可直接运行的示例:
- examples/with-vite/e2e.config.ts
- examples/with-next/e2e.config.ts
- examples/with-expo/e2e.config.ts
- examples/with-swiftui/e2e/e2e.config.ts
Vite 示例应用的被测页面长这样,跑通它只需要上面那份最小配置:
更细的字段语义、错误码(INVALID_CONFIG、UNSUPPORTED_ARTIFACT等)和完整 TypeScript 接口定义,查阅 docs/reference/config.mdx 即可。
【免费下载链接】e2eNext generation e2e testing framework for web and mobile apps.项目地址: https://gitcode.com/GitHub_Trending/e2e6/e2e
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考