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

求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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 23:45:04