视觉测试
它能做什么?
WebdriverIO提供屏幕、元素或整个页面的图像比较功能,适用于:
- 🖥️ 桌面浏览器(Chrome / Firefox / Safari / Microsoft Edge)
- 📱 移动/平板浏览器(通过Appium在Android模拟器上的Chrome / iOS模拟器上的Safari / 模拟器 / 真实设备)
- 📱 原生应用(通过Appium在Android模拟器 / iOS模拟器 / 真实设备上)(🌟 新功能 🌟)
- 📳 通过Appium的混合应用
这些功能通过轻量级WebdriverIO服务@wdio/visual-service提供。
这使您能够:
- 保存或比较屏幕/元素/整页截图与基准图像
- 当没有基准图像时自动创建基准
- 屏蔽自定义区域,甚至在比较期间自动排除状态栏和工具栏(仅限移动设备)
- 增加元素尺寸截图
- 在网站比较期间隐藏文本,以:
- 提高稳定性并防止字体渲染不稳定
- 只关注网站的布局
- 使用不同的比较方法和一组额外的匹配器,使测试更易读
- 验证您的网站如何支持键盘Tab键导航,参见通过网站Tab导航
- 以及更多功能,查看服务和方法选项
该服务是一个轻量级模块,用于为所有浏览器/设备检索所需的数据和截图。比较功能来自ResembleJS。如果您想在线比较图像,可以查看在线工具。
方法saveScreen、saveElement、checkScreen、checkElement以及匹配器toMatchScreenSnapshot和toMatchElementSnapshot可用于原生应用/上下文。
如果您想将其用于混合应用,请在服务设置中使用isHybridApp:true属性。
安装
最简单的方法是通过以下命令将@wdio/visual-service作为开发依赖保存在您的package.json中:
npm install --save-dev @wdio/visual-service
使用方法
@wdio/visual-service可以作为普通服务使用。您可以在配置文件中按以下方式设置:
import path from "node:path";
// wdio.conf.ts
export const config = {
// ...
// =====
// Setup
// =====
services: [
[
"visual",
{
// 一些选项,查看文档了解更多
baselineFolder: path.join(process.cwd(), "tests", "baseline"),
formatImageName: "{tag}-{logName}-{width}x{height}",
screenshotPath: path.join(process.cwd(), "tmp"),
savePerInstance: true,
// ... 更多选项
},
],
],
// ...
};
更多服务选项可以在这里找到。
在WebdriverIO配置中设置好后,您可以继续向您的测试添加视觉断言。
能力配置
要使用视觉测试模块,您不需要向能力配置添加任何额外选项。但是,在某些情况下,您可能希望向视觉测试添加额外的元数据,例如logName。
logName允许您为每个能力分配一个自定义名称,然后可以将其包含在图像文件名中。这对于区分在不同浏览器、设备或配置上拍摄的截图特别有用。
要启用此功能,您可以在capabilities部分定义logName,并确保视觉测试服务中的formatImageName选项引用它。以下是设置方法:
import path from "node:path";
// wdio.conf.ts
export const config = {
// ...
// =====
// Setup
// =====
capabilities: [
{
browserName: 'chrome',
'wdio-ics:options': {
logName: 'chrome-mac-15', // Chrome的自定义日志名
},
}
{
browserName: 'firefox',
'wdio-ics:options': {
logName: 'firefox-mac-15', // Firefox的自定义日志名
},
}
],
services: [
[
"visual",
{
// 一些选项,查看文档了解更多
baselineFolder: path.join(process.cwd(), "tests", "baseline"),
screenshotPath: path.join(process.cwd(), "tmp"),
// 下面的格式将使用capabilities中的`logName`
formatImageName: "{tag}-{logName}-{width}x{height}",
// ... 更多选项
},
],
],
// ...
};
工作原理
-
设置
logName:- 在
capabilities部分,为每个浏览器或设备分配一个唯一的logName。例如,chrome-mac-15标识在macOS 15版本上运行的Chrome测试。
- 在
-
自定义图像命名:
-
formatImageName选项将logName集成到截图文件名中。例如,如果tag是homepage,分辨率是1920x1080,则生成的文件名可能如下所示:homepage-chrome-mac-15-1920x1080.png
-
-
自定义命名的好处:
- 区分来自不同浏览器或设备的截图变得更加容易,特别是在管理基准和调试差异时。
-
默认值说明:
- 如果在capabilities中未设置
logName,则formatImageName选项将在文件名中显示为空字符串(homepage--15-1920x1080.png)
- 如果在capabilities中未设置
WebdriverIO MultiRemote
我们也支持MultiRemote。为了使其正常工作,请确保您在capabilities中添加了wdio-ics:options,如下所示。这将确保每个截图都有自己的唯一名称。
与使用testrunner相比,编写测试不会有任何不同
// wdio.conf.js
export const config = {
capabilities: {
chromeBrowserOne: {
capabilities: {
browserName: "chrome",
"goog:chromeOptions": {
args: ["disable-infobars"],
},
// 这个!!!
"wdio-ics:options": {
logName: "chrome-latest-one",
},
},
},
chromeBrowserTwo: {
capabilities: {
browserName: "chrome",
"goog:chromeOptions": {
args: ["disable-infobars"],
},
// 这个!!!
"wdio-ics:options": {
logName: "chrome-latest-two",
},
},
},
},
};
以编程方式运行
以下是通过remote选项使用@wdio/visual-service的最小示例:
import { remote } from "webdriverio";
import VisualService from "@wdio/visual-service";
let visualService = new VisualService({
autoSaveBaseline: true,
});
const browser = await remote({
logLevel: "silent",
capabilities: {
browserName: "chrome",
},
});
// "启动"服务,将自定义命令添加到`browser`
visualService.remoteSetup(browser);
await browser.url("https://webdriver.io/");
// 或使用此方法仅保存截图
await browser.saveFullPageScreen("examplePaged", {});
// 或使用此方法进行验证。这两种方法不需要组合使用,参见FAQ
await browser.checkFullPageScreen("examplePaged", {});
await browser.deleteSession();
通过网站Tab导航
您可以通过使用键盘TAB键检查网站是否可访问。测试可访问性的这部分一直是一项耗时的(手动)工作,并且通过自动化实现相当困难。
使用saveTabbablePage和checkTabbablePage方法,您现在可以在网站上绘制线条和点来验证Tab键导航顺序。
请注意,这仅适用于桌面浏览器,不适用于移动设备。所有桌面浏览器都支持此功能。
这项工作的灵感来自Viv Richards的博客文章"AUTOMATING PAGE TABABILITY (IS THAT A WORD?) WITH VISUAL TESTING"。
可Tab导航元素的选择方式基于模块tabbable。如果有关于Tab导航的任何问题,请查看README.md,特别是更多详情部分。
工作原理
这两种方法都会在您的网站上创建一个canvas元素,并绘制线条和点来显示如果最终用户使用Tab键会导航到哪里。之后,它会创建一个全页截图,为您提供流程的良好概览。
仅在您需要创建截图而不想将其与基准图像进行比较时使用saveTabbablePage。
当您想将Tab导航流程与基准进行比较时,可以使用checkTabbablePage方法。您不需要同时使用这两种方法。如果已经创建了基准图像(可以通过在实例化服务时提供autoSaveBaseline: true自动完成),
则checkTabbablePage将首先创建_实际_图像,然后将其与基准进行比较。
选项
这两种方法使用与saveFullPageScreen或
compareFullPageScreen相同的选项。
示例
这是Tab导航在我们的测试网站上如何工作的示例:

自动更新失败的视觉快照
通过添加参数--update-visual-baseline在命令行中更新基准图像。这将
- 自动复制实际拍摄的截图并将其放入基准文件夹
- 如果有差异,它将让测试通过,因为基准已更新
用法:
npm run test.local.desktop --update-visual-baseline
在日志信息/调试模式下运行时,您将看到以下添加的日志:
[0-0] ..............
[0-0] #####################################################################################
[0-0] INFO:
[0-0] Updated the actual image to
[0-0] /Users/wswebcreation/Git/wdio/visual-testing/localBaseline/chromel/demo-chrome-1366x768.png
[0-0] #####################################################################################
[0-0] ..........
TypeScript支持
本模块包含TypeScript支持,让您在使用视觉测试服务时能够受益于自动完成、类型安全和改进的开发体验。
步骤1:添加类型定义
为确保TypeScript识别模块类型,请在tsconfig.json的types字段中添加以下条目:
{
"compilerOptions": {
"types": ["@wdio/visual-service"]
}
}