You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让Playwright项目在Cmd+C中断时仍执行Teardown(非全局方式)

确保Playwright项目级Teardown在中断时执行的非全局方案

针对Mac上按下Cmd+C(触发SIGINT信号)中断测试时,项目级Teardown无法自动执行的问题,以下是几种不依赖全局Teardown的可行方案:

方案1:监听进程信号,单独执行Teardown项目

直接捕获中断信号,调用Playwright CLI执行指定的Teardown项目,完全复用现有Teardown代码。

实现步骤

  1. 在项目根目录创建信号处理脚本signal-handler.js:
const { execSync } = require('child_process');

process.on('SIGINT', async () => {
  console.log('\n收到中断信号,启动Teardown流程...');
  try {
    // 按顺序执行所有需要的Teardown项目
    execSync(
      'npx playwright test --project=citizen-users-teardown --project=citizen-auth-teardown',
      { stdio: 'inherit' }
    );
    process.exit(0);
  } catch (err) {
    console.error('Teardown执行失败:', err.message);
    process.exit(1);
  }
});
  1. 修改测试启动命令,预先加载该脚本:
node -r ./signal-handler.js node_modules/@playwright/test/cli.js test

优缺点

  • 优点:无需修改现有测试/Teardown代码,完全复用已有逻辑
  • 缺点:依赖命令行执行,复杂项目中需注意路径和环境变量一致性

方案2:在自定义Fixture中嵌入中断监听与清理逻辑

利用Playwright Fixture的生命周期,将Teardown逻辑绑定到fixture中,确保中断时能直接访问request上下文和自定义fixture。

实现步骤

  1. 创建包含中断处理的自定义fixture:
import { test as base } from '@playwright/test';

const test = base.extend({
  protectedRequest: async ({ request }, use) => {
    let isTeardownRunning = false;

    // 封装Teardown逻辑
    const runTeardown = async () => {
      if (isTeardownRunning) return;
      isTeardownRunning = true;
      console.log('\n触发中断,执行Fixture内Teardown');
      
      // 替换为你的实际清理逻辑
      await request.delete('/api/users/test-citizen');
      await request.delete('/api/auth/sessions/test-session');
      
      process.exit(0);
    };

    // 监听中断和终止信号
    process.on('SIGINT', runTeardown);
    process.on('SIGTERM', runTeardown);

    // 传递request上下文给测试
    await use(request);

    // 测试正常结束后移除监听
    process.off('SIGINT', runTeardown);
    process.off('SIGTERM', runTeardown);
  },
});

export default test;
  1. 在需要依赖Setup的测试中使用该fixture:
import test from '../fixtures/protected-request';

test('full functional test', async ({ protectedRequest }) => {
  // 测试逻辑
});

优缺点

  • 优点:直接集成到Playwright生态,可无缝访问所有fixture依赖
  • 缺点:需将原Teardown项目的逻辑迁移到fixture中,存在一定代码重构成本

方案3:在Setup测试文件中结合test.afterAll与信号监听

在每个Setup文件内封装Teardown逻辑,同时监听中断信号触发清理,确保正常结束和中断时都能执行。

实现步骤

以citizen-auth.setup.ts为例:

import { test } from '@playwright/test';

// 封装共享的清理逻辑
async function cleanUpAuth(request) {
  console.log('执行Auth资源清理');
  await request.delete('/api/auth/test-sessions');
}

// 监听中断信号,触发时创建新的request上下文执行清理
process.on('SIGINT', async () => {
  const tempRequest = await test.request.newContext();
  await cleanUpAuth(tempRequest);
  await tempRequest.dispose();
  process.exit(0);
});

test('setup citizen auth', async ({ request }) => {
  // 原Setup逻辑
  await request.post('/api/auth/register', { data: { username: 'test-citizen' } });
});

// 正常测试结束时执行清理
test.afterAll(async ({ request }) => {
  await cleanUpAuth(request);
});

优缺点

  • 优点:无需额外脚本,修改集中在Setup文件内
  • 缺点:需在每个Setup文件中重复添加监听逻辑,信号触发时需重新创建上下文

内容的提问来源于stack exchange,提问作者kda_100

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 00:50:16