真实场景
Day 16 - Authentication and Reusing Login State
今日目标
- 掌握 storageState。
- 避免每条测试重复登录。
- 理解登录态复用的风险。
学习时间安排(60–120 分钟)
| 时间 | 模块 | 做什么 |
|---|---|---|
| 0-20 分钟 | 核心概念与词汇 | 读概念表,重点理解 storageState 保存了什么。 |
| 20-45 分钟 | 官方文档阅读 | 读 Authentication 文档的 basic and global setup 部分。 |
| 45-75 分钟 | 实操练习 | 实现 auth.setup.ts + 登录态复用。 |
| 75-105 分钟 | 示例代码改写 | 把现有测试里的重复登录替换为 storageState。 |
| 105-120 分钟 | 复盘与作业 | 完成今日问题,检查 .gitignore 和密钥管理。 |
核心概念与词汇
| English | 中文 | 场景用法 |
|---|---|---|
storageState | 存储状态 | Use it when you save cookies and localStorage to a file for reuse. |
auth.setup.ts | 认证准备文件 | Use it when you log in once in a setup project and share the session. |
| setup project | 准备项目 | Use it when a config project runs before tests and produces shared state. |
| session | 会话 | Use it when you refer to the login state a test starts with. |
| cookie | Cookie | Use it when you explain what part of the session is stored. |
| localStorage | 本地存储 | Use it when you explain token storage in many SPAs. |
| environment variable | 环境变量 | Use it when you inject secrets like TEST_USER without hardcoding. |
| secret | 密钥 | Use it when you talk about credentials that must never be committed. |
| token expiry | 令牌过期 | Use it when you explain why saved login state can go stale. |
| multi-role testing | 多角色测试 | Use it when different roles need different saved states. |
.gitignore | 忽略文件 | Use it when you keep auth files and reports out of version control. |
学习材料
- 必读:[Authentication](https://playwright.dev/docs/auth)
- 必读:[Basic: shared account in all tests](https://playwright.dev/docs/auth#basic-shared-account-in-all-tests) 部分
- 选读:[Sign in with API request](https://playwright.dev/docs/auth#signing-in-before-each-test)(对比两种方式)
重点理解
保存登录态:
// auth.setup.ts
import { test as setup } from '@playwright/test';
setup('authenticate', async ({ page }) => {
await page.goto('/login');
await page.getByLabel('Username').fill(process.env.TEST_USER!);
await page.getByLabel('Password').fill(process.env.TEST_PASSWORD!);
await page.getByRole('button', { name: 'Login' }).click();
await page.context().storageState({ path: 'playwright/.auth/user.json' });
});
配置中使用:
use: {
storageState: 'playwright/.auth/user.json',
}
注意:
- 不要把真实账号密码提交到 Git。
.auth文件通常不要提交。- 登录态可能过期,需要刷新机制。
- 不同角色要不同 storageState。
实操步骤
实现:
- setup 登录脚本。
- 复用登录态访问已登录页面。
- 增加
.gitignore忽略 auth 文件。
示例代码
// playwright.config.ts
export default defineConfig({
projects: [
{ name: 'setup', testMatch: /auth\.setup\.ts/ },
{
name: 'chromium',
use: {
...devices['Desktop Chrome'],
storageState: 'playwright/.auth/user.json',
},
dependencies: ['setup'],
},
],
});
# 环境变量注入密钥
TEST_USER=demo TEST_PASSWORD=secret npx playwright test
常见坑
- 把真实账号密码写死在
auth.setup.ts里提交到仓库。 .auth/user.json提交进 Git,泄露有效会话。- 登录态过期后所有测试集体失败,报错全是“未登录”,排查半天。
- 多角色共用一份 storageState,权限断言互相污染。
- CI 里忘记配置环境变量,setup 项目静默失败。
今日产出
- 登录态复用方案。
- 至少一个不重复登录的测试。
今日问题
- 为什么不建议每条测试都 UI 登录?
- storageState 保存了什么?
- 登录态复用有什么风险?
- 多角色测试如何处理?
- CI 中账号密码应该怎么管理?
复盘要点
- 登录一次、处处复用,是 E2E 提速的第一个杠杆,但代价是“会话过期”这个新故障源。
- 安全底线:密钥进环境变量/CI secrets,auth 文件进 .gitignore,二者缺一不可。
- 多角色项目从第一天就用多份 storageState 命名区分(admin/user),后面不用返工。
AI 时代扩展:AI 辅助 Playwright 测试
新增概念
| English | 中文 |
|---|---|
| session management | 会话管理 |
| secret handling | 密钥处理 |
| auth strategy | 认证策略 |
适用场景
让 AI 对比“全局复用登录态”和“每次 API 登录”两种方案的取舍,或者审查你的 auth.setup.ts 是否存在密钥泄露、过期处理缺失等问题。
可复用表达 / 提示词
请对比 Playwright 中 storageState 复用和每次 API 登录两种认证策略的取舍,各列 3 个适用场景。
请审查我的 auth.setup.ts 和 config,检查密钥管理、会话过期处理、多角色扩展性。
追问加练
- AI 说“把密码直接写进环境变量文件也可以”,你接受吗?
- 会话过期时,AI 能帮你设计什么样的检测机制?
- 多角色登录态,AI 建议每角色一个 setup project,你评估一下。
今日作业
- 完成 auth.setup.ts + storageState 复用,跑通不重复登录的测试。
- 在 .gitignore 中加入
playwright/.auth/,并验证 git status 不显示它。 - 让 AI 审查你的认证方案,重点核对密钥是否可能进入仓库。