求Playwright中保存Token供后续API测试使用的TypeScript示例
在TypeScript测试中存储与复用API Token的实用方案
为什么不推荐直接写入.env?
.env 通常用于存储静态配置(如客户端ID、密钥),动态写入容易覆盖原有配置,还可能引发版本控制问题(需确保.env在.gitignore中)。更推荐用测试框架的全局上下文或临时文件存储动态生成的Token。
方案1:利用Playwright全局Setup共享Token(推荐)
从代码中的request参数判断你的测试基于Playwright,可通过全局Setup脚本预先获取Token,注入到所有测试用例的环境中。
步骤1:创建全局Setup文件
新建global-setup.ts:
import { FullConfig } from '@playwright/test'; import fs from 'fs/promises'; async function globalSetup(config: FullConfig) { // 复用你的Token获取逻辑 const response = await fetch('https://your-token-endpoint', { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, body: new URLSearchParams({ "client_id": "your-client-id", "scope": "your-scope", "grant_type": "client_credentials", "client_secret": "your-client-secret" }).toString() }); if (!response.ok) throw new Error('获取Token失败'); const resBody = await response.json(); const token = resBody.access_token; // 方式1:存入环境变量 process.env.TEST_ACCESS_TOKEN = token; // 方式2:写入临时文件(可选,适合跨进程共享) await fs.writeFile('./temp-token.json', JSON.stringify({ accessToken: token })); } export default globalSetup;
步骤2:配置Playwright使用Setup
修改playwright.config.ts:
import { defineConfig } from '@playwright/test'; export default defineConfig({ globalSetup: './global-setup.ts', });
步骤3:在测试用例中使用Token
import fs from 'fs/promises'; test('使用存储的Token调用API', async ({ request }) => { // 从环境变量读取 const token = process.env.TEST_ACCESS_TOKEN; // 或从临时文件读取(如果用了方式2) // const tokenData = JSON.parse(await fs.readFile('./temp-token.json', 'utf-8')); // const token = tokenData.accessToken; if (!token) throw new Error('未找到有效Token'); const response = await request.get('https://your-api-endpoint', { headers: { 'Authorization': `Bearer ${token}` } }); expect(response.status()).toBe(200); });
方案2:同一测试文件内串行共享Token
如果所有相关测试在同一个文件中,可通过串行测试组共享Token变量。
test.describe.serial('带Token验证的API测试', () => { let accessToken: string; test('获取access_token', async ({ request }) => { const response = await request.post('https://your-token-endpoint', { headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, data: new URLSearchParams({ "client_id": "your-client-id", "scope": "your-scope", "grant_type": "client_credentials", "client_secret": "your-client-secret" }).toString() }); expect(response.status()).toBe(200); const resBody = await response.json(); // 直接用response.json()替代JSON.parse(text) accessToken = resBody.access_token; expect(resBody.token_type).toBe("Bearer"); }); test('使用Token调用业务API', async ({ request }) => { expect(accessToken).toBeDefined(); // 确保Token已获取 const response = await request.get('https://your-business-api', { headers: { 'Authorization': `Bearer ${accessToken}` } }); expect(response.status()).toBe(200); }); });
注:test.describe.serial确保测试按顺序执行,避免并行导致的Token未就绪问题。
方案3:动态写入.env(不推荐)
如果必须写入.env,可通过文件读写实现,但需注意覆盖风险和版本控制。
步骤1:安装依赖
npm install dotenv --save-dev
步骤2:写入Token到.env
import fs from 'fs/promises'; test('获取并保存Token到.env', async ({ request }) => { const response = await request.post('https://your-token-endpoint', { headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, data: new URLSearchParams({ "client_id": "your-client-id", "scope": "your-scope", "grant_type": "client_credentials", "client_secret": "your-client-secret" }).toString() }); expect(response.status()).toBe(200); const resBody = await response.json(); const token = resBody.access_token; expect(resBody.token_type).toBe("Bearer"); // 读取现有.env内容 let envContent = ''; try { envContent = await fs.readFile('.env', 'utf-8'); } catch (err) { // 文件不存在则创建空内容 } // 替换或添加TEST_ACCESS_TOKEN变量 const tokenLine = `TEST_ACCESS_TOKEN=${token}`; const regex = /^TEST_ACCESS_TOKEN=.*/m; envContent = regex.test(envContent) ? envContent.replace(regex, tokenLine) : `${envContent}\n${tokenLine}`; // 写入.env文件 await fs.writeFile('.env', envContent, 'utf-8'); });
步骤3:从.env读取Token
import dotenv from 'dotenv'; dotenv.config(); // 加载.env内容到环境变量 test('从.env读取Token调用API', async ({ request }) => { const token = process.env.TEST_ACCESS_TOKEN; if (!token) throw new Error('.env中未找到TEST_ACCESS_TOKEN'); const response = await request.get('https://your-api-endpoint', { headers: { 'Authorization': `Bearer ${token}` } }); expect(response.status()).toBe(200); });
内容的提问来源于stack exchange,提问作者Andre Hesdahl
相关产品推荐
相关产品推荐

