Skip to content

Playwright 认证(Authentication)

本章介绍如何在 Playwright 中处理认证,避免每个测试都重复登录,同时保持测试的隔离性。


认证的核心问题

大多数 Web 应用的测试都需要用户登录。

如果每个测试都从头执行登录流程,会显著拖慢测试速度。

Playwright 的解决方案是:认证一次,保存状态,所有测试复用


准备工作:.auth 目录

实例

bash

# 创建认证状态存储目录

mkdir -p playwright/.auth

# 添加到 .gitignore(认证状态包含机密信息)

echo 'playwright/.auth' >> .gitignore

.auth 文件包含敏感 Cookie 和认证 Token,绝对不能提交到代码仓库


基本方案:共享账号 + Setup 项目

这是 Playwright 推荐的认证方案,适用于所有测试共享同一个测试账号的场景。

第一步:创建认证 Setup

实例

javascript

// 文件路径:tests/auth.setup.ts

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

// 指定认证状态保存路径

const authFile = 'playwright/.auth/user.json';

setup('authenticate', async ({ page }) => {

  // 执行登录操作

  await page.goto('https://www.runoob.com/login');

  await page.getByLabel('用户名').fill('testuser');

  await page.getByLabel('密码').fill('password123');

  await page.getByRole('button', { name: '登录' }).click();

  // 等待登录完成(确认页面跳转或出现用户信息)

  await page.waitForURL(/dashboard/);

  // 将当前的认证状态(Cookie、localStorage)保存到文件

  await page.context().storageState({ path: authFile });

});

第二步:配置 Setup 项目

实例

bash

// 文件路径:playwright.config.ts

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

export default defineConfig({

  projects: [

    // Setup 项目 —— 只运行一次,生成认证状态文件

    {

      name: 'setup',

      testMatch: /auth\.setup\.ts/,

    },

    // 实际测试项目 —— 复用认证状态

    {

      name: 'chromium',

      use: {

        storageState: 'playwright/.auth/user.json',

      },

      dependencies: ['setup'],    // 依赖 setup 项目,确保 setup 先运行

    },

  ],

});

第三步:测试直接使用认证状态

实例

javascript

// 文件路径:tests/dashboard.spec.ts

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

test('查看仪表盘', async ({ page }) => {

  // 直接访问需要登录的页面,page 已经带着认证状态

  await page.goto('/dashboard');

  await expect(page.getByText('欢迎回来,testuser')).toBeVisible();

});

多账号场景

如果不同测试需要使用不同账号,可以创建多个认证状态文件。

实例

javascript

// 管理员测试

test.describe('管理员功能', () => {

  test.use({ storageState: 'playwright/.auth/admin.json' });

  test('管理用户', async ({ page }) => {

    // 以管理员身份操作

  });

});

// 普通用户测试

test.describe('普通用户功能', () => {

  test.use({ storageState: 'playwright/.auth/user.json' });

  test('浏览内容', async ({ page }) => {

    // 以普通用户身份操作

  });

});

通过 API 请求认证(推荐)

通过 UI 执行登录流程较慢,更高效的方式是直接调用登录 API。

实例

javascript

// 文件路径:tests/auth.setup.ts

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

const authFile = 'playwright/.auth/user.json';

setup('通过 API 认证', async ({ request }) => {

  // 直接调用登录 API,不通过浏览器 UI

  const response = await request.post('https://www.runoob.com/api/login', {

    data: {

      username: 'testuser',

      password: 'password123',

    },

  });

  // 确认登录成功

  const json = await response.json();

  console.log('登录成功,Token:', json.token);

  // 将 Token 保存为 Cookie(模拟浏览器认证状态)

  // 注意:storageState 需要在浏览器 Context 中保存

});

API 认证比 UI 认证更快更可靠,推荐在实际项目中优先使用。


认证方案的适用场景总结

场景推荐方案
所有测试用同一个测试账号Setup 项目 + storageState
不同类型测试需要不同账号多个 storageState + test.use
每个测试需要独立账号每个测试内 API 创建账号并登录
账号资源有限Setup 项目认证一次,全部复用

AI 思考中...

Playwright 测试隔离与 Browser Context

Playwright 配置详解

基于 VitePress 构建,部署于 GitHub Pages