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

如何在Playwright全局清理中访问测试内定义的环境变量?

问题

在Playwright测试用例(spec.ts)中,通过process.env.id = await userAction.createUser();给环境变量赋值,日志显示该值已正确设置,但在global.teardown.ts的全局清理函数中访问process.env.id时返回undefined,尝试设置global.process.env = process.env;后问题依旧。

测试代码片段:

test.describe('tests', () => {
  test('create a user', async ({ page, userAction }) => {
    process.env.id = await userAction.createUser();
    console.log(`create user with ${process.env.id}`);
    // 其他测试逻辑
  });
});

全局清理代码片段:

teardown('Delete user after the test', async ({ userAction }) => {
  const userId = process.env.id || '';
  console.log(`teardown the user ${userId}`);
  // 清理逻辑
});

核心原因

Playwright的测试执行进程和全局清理进程是完全独立的Node.js进程,测试进程内修改的process.env属于进程私有变量,不会自动共享到清理进程,这就是值无法访问的根本原因。


解决方法

方法1:利用测试上下文传递数据(推荐)

Playwright的testInfo对象可以在测试用例和全局清理间传递数据,无需依赖外部存储:

修改测试用例:

test.describe('tests', () => {
  test('create a user', async ({ page, userAction }, testInfo) => {
    const userId = await userAction.createUser();
    // 将用户ID存入测试上下文的storageState
    testInfo.storageState.userId = userId;
    console.log(`create user with ${userId}`);
    // 其他测试逻辑
  });
});

修改全局清理:

teardown('Delete user after the test', async ({ userAction }, testInfo) => {
  const userId = testInfo.storageState.userId || '';
  console.log(`teardown the user ${userId}`);
  if (userId) {
    await userAction.deleteUser(userId);
  }
});

方法2:写入临时文件实现跨进程共享

将生成的用户ID写入本地临时文件,全局清理时读取该文件:

修改测试用例:

import fs from 'fs/promises';
import path from 'path';

test.describe('tests', () => {
  test('create a user', async ({ page, userAction }) => {
    const userId = await userAction.createUser();
    // 写入临时文件
    await fs.writeFile(path.join(__dirname, 'temp-user-id.txt'), userId);
    console.log(`create user with ${userId}`);
    // 其他测试逻辑
  });
});

修改全局清理:

import fs from 'fs/promises';
import path from 'path';

teardown('Delete user after the test', async ({ userAction }) => {
  let userId = '';
  try {
    // 读取临时文件中的用户ID
    userId = await fs.readFile(path.join(__dirname, 'temp-user-id.txt'), 'utf8');
  } catch (e) {
    console.log('未找到需要清理的用户ID');
  }
  
  console.log(`teardown the user ${userId}`);
  if (userId) {
    await userAction.deleteUser(userId);
    // 清理临时文件
    await fs.unlink(path.join(__dirname, 'temp-user-id.txt'));
  }
});

方法3:使用全局变量(适合多测试用例共享场景)

通过globalSetup初始化全局存储,在测试用例中写入数据,全局清理时读取:

创建global.setup.ts:

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

setup('初始化全局存储', async () => {
  // 扩展global对象添加测试存储
  (global as any).testStorage = {};
});

修改测试用例:

test.describe('tests', () => {
  test('create a user', async ({ page, userAction }) => {
    const userId = await userAction.createUser();
    (global as any).testStorage.userId = userId;
    console.log(`create user with ${userId}`);
    // 其他测试逻辑
  });
});

修改全局清理:

teardown('Delete user after the test', async ({ userAction }) => {
  const userId = (global as any).testStorage.userId || '';
  console.log(`teardown the user ${userId}`);
  if (userId) {
    await userAction.deleteUser(userId);
  }
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 12:40:12