如何在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
相关产品推荐
相关产品推荐

