跳到主要内容

可视化对比

简介

Playwright Test 提供了通过 await expect(page).toHaveScreenshot() 生成和可视化比较截图的能力。首次执行时,Playwright 测试会生成参考截图。后续运行将与此参考截图进行比较。

example.spec.ts
import { test, expect } from '@playwright/test';

test('example test', async ({ page }) => {
await page.goto('https://playwright.dev');
await expect(page).toHaveScreenshot();
});
注意

浏览器渲染可能会因主机操作系统、版本、设置、硬件、电源(电池 vs 电源适配器)、无头模式等因素而有所不同。为了获得一致的截图,请在生成基线截图相同的环境中运行测试。

生成截图

当你第一次运行上述测试时,测试运行器会显示:

Error: 快照文件不存在于 example.spec.ts-snapshots/example-test-1-chromium-darwin.png 路径,正在写入实际截图。

这是因为此时还没有基准参考文件(golden file)。该方法会持续截取多张截图,直到连续两张截图完全匹配为止,并将最后一张截图保存到文件系统中。现在这个文件可以提交到代码仓库了。

存放基准参考文件的文件夹名称以测试文件名为前缀:

drwxr-xr-x  5 user  group  160 Jun  4 11:46 .
drwxr-xr-x 6 user group 192 Jun 4 11:45 ..
-rw-r--r-- 1 user group 231 Jun 4 11:16 example.spec.ts
drwxr-xr-x 3 user group 96 Jun 4 11:46 example.spec.ts-snapshots

快照文件名 example-test-1-chromium-darwin.png 由以下几部分组成:

  • example-test-1.png - 自动生成的快照名称。你也可以通过 toHaveScreenshot() 方法的第一个参数指定快照名:

    await expect(page).toHaveScreenshot('landing.png');
  • chromium-darwin - 浏览器名称和平台类型。由于不同浏览器和平台的渲染效果、字体等存在差异,因此需要为它们保存不同的快照。如果在配置文件中使用了多个项目(project),则会用项目名称替代 chromium

快照名称和路径可以通过 playwright 配置中的 testConfig.snapshotPathTemplate 进行配置。

更新截图

有时您需要更新参考截图,例如当页面发生变化时。可以使用 --update-snapshots 标志来实现:

npx playwright test --update-snapshots

注意:snapshotName 也接受指向快照文件的路径片段数组,例如 expect().toHaveScreenshot(['relative', 'path', 'to', 'snapshot.png'])。 但是,此路径必须保持在每个测试文件的快照目录内(即 a.spec.js-snapshots),否则会抛出错误。

选项

maxDiffPixels

Playwright Test 使用 pixelmatch 库。您可以传递各种选项来修改其行为:

example.spec.ts
import { test, expect } from '@playwright/test';

test('example test', async ({ page }) => {
await page.goto('https://playwright.dev');
await expect(page).toHaveScreenshot({ maxDiffPixels: 100 });
});

如果您希望在项目中的所有测试之间共享默认值,可以在 playwright 配置中全局或按项目指定:

playwright.config.ts
import { defineConfig } from '@playwright/test';
export default defineConfig({
expect: {
toHaveScreenshot: { maxDiffPixels: 100 },
},
});

stylePath

您可以在截图时向页面应用自定义样式表。这可以过滤掉动态或易变的元素,从而提高截图的确定性。

screenshot.css
iframe {
visibility: hidden;
}
example.spec.ts
import { test, expect } from '@playwright/test';

test('example test', async ({ page }) => {
await page.goto('https://playwright.dev');
await expect(page).toHaveScreenshot({ stylePath: path.join(__dirname, 'screenshot.css') });
});

如果您希望在项目中所有测试间共享默认值,可以在 playwright 配置中全局或按项目指定:

playwright.config.ts
import { defineConfig } from '@playwright/test';
export default defineConfig({
expect: {
toHaveScreenshot: {
stylePath: './screenshot.css'
},
},
});

非图像快照

除了截图之外,您还可以使用 expect(value).toMatchSnapshot(snapshotName) 来比较文本或任意二进制数据。Playwright Test 会自动检测内容类型并使用适当的比较算法。

这里我们将文本内容与参考值进行比较。

example.spec.ts
import { test, expect } from '@playwright/test';

test('example test', async ({ page }) => {
await page.goto('https://playwright.dev');
expect(await page.textContent('.hero__title')).toMatchSnapshot('hero.txt');
});

快照会存储在测试文件旁边的单独目录中。例如,my.spec.ts 文件将在 my.spec.ts-snapshots 目录中生成和存储快照。您应该将此目录提交到版本控制系统(如 git),并审查其中的任何更改。