全局 setup / teardown
本教程共 59 篇 · 第 40 篇 · 更新于 2026-08-04 · 约 10 分钟阅读
本节目标:学完能在整套测试跑之前做一次性准备(建库、登录),跑之后做清理,并知道两种实现方式的取舍。
Fixture(夹具)管「每条测试」,钩子管「每个文件」。那「整套测试之前之后」这种事谁管?这就是全局 setup(前置准备)和 teardown(收尾清理)的活儿。
两种做法
Playwright 提供两条路:
- 项目依赖(setup 项目):官方推荐,把准备写成一个普通测试项目。
globalSetup/globalTeardown:写在配置里的两个函数,全局只跑一次。
Note项目依赖方式能享受 HTML 报告、trace 记录、夹具支持等全套能力;
globalSetup则是「裸奔」运行,能力受限。
推荐:项目依赖方式
先在配置里加一个 setup 项目,专门匹配你的准备脚本:
// playwright.config.ts
import { defineConfig, devices } from '@playwright/test';
export default defineConfig({
testDir: './tests',
projects: [
{ name: 'setup db', testMatch: /global\.setup\.ts/ },
{
name: 'chromium with db',
use: { ...devices['Desktop Chrome'] },
dependencies: ['setup db'], // 先跑 setup
},
],
});
准备脚本本身就是一个普通测试:
// tests/global.setup.ts
import { test as setup } from '@playwright/test';
setup('创建测试数据库', async ({ }) => {
console.log('creating new database...');
// 初始化数据库
});
你的业务测试照常写,它会自动等 setup 跑完再执行。
配套 teardown
准备之后要清理?给 setup 项目配一个 teardown 项目,它在所有依赖项目跑完后才执行:
// playwright.config.ts(只列 projects 部分)
projects: [
{ name: 'setup db', testMatch: /global\.setup\.ts/, teardown: 'cleanup db' },
{ name: 'cleanup db', testMatch: /global\.teardown\.ts/ },
{
name: 'chromium',
use: { ...devices['Desktop Chrome'] },
dependencies: ['setup db'],
},
]
// tests/global.teardown.ts
import { test as teardown } from '@playwright/test';
teardown('删除测试数据库', async ({ }) => {
console.log('deleting test database...');
// 清理
});
备选:globalSetup / globalTeardown
如果你只想要「跑一次」且不需要报告与夹具,可以用配置里的函数式入口:
// playwright.config.ts
import { defineConfig } from '@playwright/test';
export default defineConfig({
globalSetup: require.resolve('./global-setup'),
globalTeardown: require.resolve('./global-teardown'),
});
// global-setup.ts
import { chromium, type FullConfig } from '@playwright/test';
async function globalSetup(config: FullConfig) {
const { baseURL, storageState } = config.projects[0].use;
const browser = await chromium.launch();
const page = await browser.newPage();
await page.goto(baseURL!);
await page.getByLabel('User Name').fill('user');
await page.getByLabel('Password').fill('password');
await page.getByText('Sign in').click();
await page.context().storageState({ path: storageState as string });
await browser.close();
}
export default globalSetup;
Warning
globalSetup里没有request、page这些夹具,浏览器得自己chromium.launch()手动管。缺少报告与 trace,调试不便。
和登录态复用的关系
第 33 章讲的登录态复用,本质就是拿全局 setup 把「登录」做成一次性准备。比起在每套测试里都走一遍完整的登录流程,用 setup 项目统一处理更干净,而且这一步会作为独立的测试项出现在报告里,出问题时一眼就能看到是准备阶段挂了。
Tip如果全局准备本身也可能失败,把 trace 打开很有用。setup 项目跑的测试同样支持
trace配置,失败时直接回放准备过程,比盲猜快得多。
两者之间怎么选
| 维度 | 项目依赖(推荐) | globalSetup |
|---|---|---|
| 报告显示 | 单独一项可见 | 不显示 |
| Trace(追踪)记录 | 完整支持 | 不支持 |
| 夹具支持 | 完整 | 无 |
| 浏览器管理 | 走 browser 夹具 | 手动 launch |
我的建议:能上项目依赖就上项目依赖,尤其是登录态复用和建库这种场景。只有极简的一次性准备,才考虑 globalSetup。
一个细节
筛选测试时(如 --grep、--shard、点 test.only),只要选中的测试属于某个带依赖的项目,它的依赖项目也会一起跑。想强行忽略,加 --no-deps。第 44 章讲分片时你会再见到这个配合。
小结
全局 setup 管的是整套测试前后那一次性的活儿,比如建库、登录。官方推荐用「项目依赖」方式——写个专门的 setup 测试项目,通过 dependencies 让业务测试等它跑完再开始,这样能享受报告和 trace。globalSetup 是备选,裸奔运行没有夹具也没有报告,除非极简场景否则不推荐。