视觉对比测试 Visual Comparisons
本教程共 59 篇 · 第 48 篇 · 更新于 2026-08-04 · 约 7 分钟阅读
48. 视觉对比测试 Visual Comparisons
本节目标:学完你能用一张截图当「标准答案」,之后每次跑测试自动比对新旧图,发现页面长相变了。
普通的断言查的是文字、数值。可页面「长得对不对」光看文字查不出来。Visual Comparison(视觉对比)就是让 Playwright 帮你「看」一眼:截图存成基准,下次跑再截一次,逐像素比对。
它怎么工作
核心方法是 expect(page).toHaveScreenshot()。第一次跑没有基准图,它会先生成一张,存进仓库。之后再跑,就拿新图跟基准图比。
import { test, expect } from '@playwright/test';
test('example test', async ({ page }) => {
await page.goto('https://playwright.dev');
await expect(page).toHaveScreenshot();
});
第一次跑会发生什么
你第一次执行,终端会提示「没有基准图,先写一份」:
Error: A snapshot doesn't exist at example.spec.ts-snapshots/example-test-1-chromium-darwin.png, writing actual.
它连续截几张、直到两张一致,再把最后一张存盘。这份图要提交进 git,当标准答案。
Warning不同操作系统、不同浏览器、甚至插不插电源,渲染都可能略有差异。想结果稳,就在生成基准的同一环境里跑对比测试。
基准图的命名
基准图默认放在 你的测试文件-snapshots/ 目录里。文件名带两部分:
example-test-1.png:自动起的快照名。你也可以自己起名:toHaveScreenshot('landing.png')。chromium-darwin:浏览器名加平台。不同浏览器、平台截图不一样,要各存一份。配置里用了多个 project 时,这里显示的是项目名。
想要 WebP 格式(同样无损、更小),把扩展名写成 .webp:
await expect(page).toHaveScreenshot('landing.webp');
Tip嫌默认目录结构别扭,可以在配置里用
snapshotPathTemplate自定义基准图的存放路径和命名规则。
更新基准图
页面真的改版了,旧基准就该换。用这个命令重生成:
npx playwright test --update-snapshots
Tip更新前先 review 差异。别脑子一热全量更新,把真回归也顺手盖掉了。
容忍一点点差异
像素不可能 100% 一样。Playwright 底层用的是 pixelmatch 这个库,用 maxDiffPixels 设允许的最大不同像素数:
await expect(page).toHaveScreenshot({ maxDiffPixels: 100 });
想全项目共用一个值,写进配置:
import { defineConfig } from '@playwright/test';
export default defineConfig({
expect: {
toHaveScreenshot: { maxDiffPixels: 100 },
},
});
过滤掉会动的元素
有些东西每回不一样:广告 iframe、时间戳、动画。用 stylePath 套一张样式表,把它们藏起来,截图就稳定了。
/* screenshot.css */
iframe {
visibility: hidden;
}
import { test, expect } from '@playwright/test';
import path from 'path';
test('example test', async ({ page }) => {
await page.goto('https://playwright.dev');
await expect(page).toHaveScreenshot({
stylePath: path.join(__dirname, 'screenshot.css'),
});
});
不止比图片
除了整页截图,还能比纯文本或任意二进制数据。Playwright 会自动判断内容类型,选合适的比对算法:
import { test, expect } from '@playwright/test';
test('标题文案没变', async ({ page }) => {
await page.goto('https://playwright.dev');
expect(await page.textContent('.hero__title')).toMatchSnapshot('hero.txt');
});
快照同样存在测试文件旁边的 *-snapshots 目录,记得提交进版本库。这类非图片快照,第 49 章还会细讲。
什么时候用它
视觉对比适合「整页或整块 UI 长相基本不变」的场景,比如组件库、官网首屏。内容天天变的动态页面别硬上,否则天天误报。
一句话:视觉对比是「看长相」的测试,基准图进 git,改版用 --update-snapshots 重生成。
小结
视觉对比就是「看长相」的测试,基准图锁进 git,改版用 —update-snapshots 重生成。它适合 UI 长得基本不变的场景,动态内容多的页面别硬上,否则天天误报。maxDiffPixels 和 stylePath 是稳定截图的两大法宝,一个容忍像素差,一个藏掉会动的东西。