Previous
Day 25 · Weekly Review 5: A Sustainably Running Test Suite
Next
Day 27 · Accessibility and User-Behavior Testing
进阶掌握
Day 2660-120 minutesPlaywright QA hands-on drill

第 26 天:视觉测试与截图对比

今日目标

  • 了解 Playwright 的 screenshot assertion。
  • 能判断视觉测试适合哪些场景。

学习时间安排(60–120 分钟)

时间模块做什么
0-20 分钟核心概念与词汇读概念表,重点理解 baseline 和 mask 的作用。
20-45 分钟官方文档阅读读 Visual comparisons 文档的 toHaveScreenshot 部分。
45-75 分钟实操练习为稳定页面添加截图对比测试,体验失败与更新流程。
75-105 分钟示例代码改写尝试 mask 动态区域,减少误报。
105-120 分钟复盘与作业完成视觉测试适用场景清单,完成今日问题。

核心概念与词汇

English中文场景用法
toHaveScreenshot()截图对比断言用于说明该术语在 Playwright 测试中的使用场景。
baseline基线截图用于说明该术语在 Playwright 测试中的使用场景。
diff差异图用于说明该术语在 Playwright 测试中的使用场景。
mask掩码用于说明该术语在 Playwright 测试中的使用场景。
pixel comparison像素对比用于说明该术语在 Playwright 测试中的使用场景。
visual regression视觉回归用于说明该术语在 Playwright 测试中的使用场景。
anti-aliasing抗锯齿用于说明该术语在 Playwright 测试中的使用场景。
deterministic rendering确定性渲染用于说明该术语在 Playwright 测试中的使用场景。
snapshot update基线更新用于说明该术语在 Playwright 测试中的使用场景。
false positive误报用于说明该术语在 Playwright 测试中的使用场景。

学习材料

  • 必读:[Visual comparisons](https://playwright.dev/docs/test-snapshots)
  • 必读:[toHaveScreenshot 文档](https://playwright.dev/docs/api/class-pageassertions#page-assertions-to-have-screenshot-1)
  • 选读:[Screenshots](https://playwright.dev/docs/screenshots)(普通截图 vs 对比截图)

重点理解

示例:

await expect(page).toHaveScreenshot();
await expect(page.getByRole('main')).toHaveScreenshot('main-section.png');

注意:

  • 视觉测试容易受字体、系统、浏览器版本影响。
  • 更适合关键页面、组件、布局回归。
  • 不适合频繁变化的动态内容。
  • CI 环境应固定浏览器版本和渲染环境。
  • 需要合理 mask 动态区域。

实操步骤

为一个稳定页面添加截图对比测试:

  1. 首次生成 baseline。
  2. 修改页面或尺寸触发失败。
  3. 查看 diff。
  4. 尝试 mask 动态区域。

示例代码

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

test('homepage layout is stable', async ({ page }) => {
  await page.goto('/');

  await expect(page).toHaveScreenshot('homepage.png', {
    // 屏蔽动态区域:广告位、时间、随机推荐
    mask: [
      page.getByRole('banner').locator('.ads'),
      page.locator('.recommendation-list'),
    ],
    maxDiffPixels: 100,
  });
});
# 首次生成基线
npx playwright test tests/visual.spec.ts --update-snapshots

# 后续对比失败后查看 diff,确认是有意改动再更新
npx playwright test tests/visual.spec.ts

常见坑

  • 动态内容(时间、广告、推荐流)不 mask,每次跑都误报。
  • 本地 macOS 和 CI Linux 字体渲染不同,基线两边不一致。
  • 把视觉测试铺到所有页面,维护成本爆炸。
  • 基线更新太随意:不先看 diff 就 --update-snapshots,把 bug 当基线。
  • 像素级全页对比,任何一行文案改动都全红。

今日产出

  • 一个视觉测试示例。
  • 一份视觉测试适用场景清单。

今日问题

  1. 视觉测试和功能测试有什么区别?
  2. 哪些页面适合截图对比?
  3. 为什么动态内容会导致误报?
  4. baseline 应该如何维护?
  5. 视觉测试是否应该放在 PR 阶段?

复盘要点

  • 视觉测试抓的是“长坏了”而不是“不能用了”:布局、样式、渲染回归。
  • 选页面要克制:关键页、组件级、变化少,三条标准缺一不可。
  • baseline 是契约:更新前必须看 diff,确认是有意改动。

AI 时代扩展:AI 辅助 Playwright 测试

新增概念

English中文
visual diff triage视觉差异分类
dynamic masking动态区域掩码
visual acceptance视觉验收

适用场景

让 AI 根据页面描述建议哪些区域需要 mask,或者根据 diff 描述判断改动是否属于预期。AI 看不了图片时,可以让它基于你提供的 diff 文本/尺寸信息辅助判断。

可复用表达 / 提示词

我的首页有轮播图、实时时间、推荐流三块动态内容,请设计 toHaveScreenshot 的 mask 方案并说明理由。
视觉测试失败,diff 显示页头按钮组整体右移 20px,请分析最可能的 3 个原因。

追问加练

  • AI 建议 mask 掉整个页头,代价是什么?
  • diff 判定“有意改动”和“意外回归”的标准由谁定?
  • 视觉测试的误报率如何度量?

今日作业

  • 完成 1 个页面级 + 1 个组件级视觉测试并跑通。
  • 完成视觉测试适用场景清单:至少 5 条选择标准。
  • 让 AI 审查你的 mask 方案,补充遗漏的动态区域。

自检清单

Previous
Day 25 · Weekly Review 5: A Sustainably Running Test Suite
Next
Day 27 · Accessibility and User-Behavior Testing