跳至主要内容

组件、端到端和移动测试的 DOM 和视觉快照测试简介

·6 分钟阅读

我们很高兴地宣布支持使用一组支持 WebdriverIO 提供的所有测试环境的通用原语的 DOM 和视觉快照测试。我们的愿景一直是提供一个全面、通用的测试工具,简化您的工作流程。此更新是朝着创建用于单元和视觉测试的“瑞士军刀”迈出的一步,满足跨平台的多样化需求,并将我们的支持扩展到原生移动应用程序,使您的测试流程更高效、更无缝。

在运行组件和单元测试、端到端测试以及移动 Web 测试时,DOM 和视觉快照原语都可供您使用。除此之外,相同的视觉快照原语也可用于原生移动应用程序测试。

如果您更喜欢视觉学习,我们还在我们的YouTube频道上发布了 WebdriverIO 教程

让我们深入了解这些强大的功能。

DOM 或对象快照

为了评估 DOM、大型对象或 UI 元素内容的状态,我们通常倾向于将值复制到我们的测试中,并在更改应用程序或组件的行为时手动更新它。

使用基于文本的快照,我们可以让 WebdriverIO 处理它。例如,假设我们要验证 React 组件在浏览器中的状态,我们可以执行以下操作

/src/component.test.tsx
import { expect, $ } from '@wdio/globals'
import { render } from '@testing-library/react'

function App() {
const [theme, setTheme] = useState('light')

const toggleTheme = () => {
const nextTheme = theme === 'light' ? 'dark' : 'light'
setTheme(nextTheme)
}

return <button onClick={toggleTheme}>
Current theme: {theme}
</button>
}

describe('React Component Testing', () => {
it('supports snapshot tests', async () => {
const { container } = render(<App />)
await expect(container).toMatchSnapshot()
await $('button').click()
await expect(container).toMatchSnapshot()
})
})

WebdriverIO 将自动获取组件的 DOM 结构,并在 /src/__snapshots__ 目录中,与您的测试文件 component.test.tsx.snap 相邻的位置存储一个快照文件,其内容如下

// Snapshot v1

exports[`React Component Testing > supports snapshot tests 1`] = `"<div><button>Current theme: light</button></div>"`;

exports[`React Component Testing > supports snapshot tests 2`] = `"<div><button>Current theme: dark</button></div>"`;

如果您希望将快照保留为测试的一部分,则可以使用 toMatchInlineSnapshot 代替

await expect(container).toMatchInlineSnapshot()

第一次运行测试后,WebdriverIO 将对测试进行更改,并在其中填充快照

await expect(container).toMatchInlineSnapshot(`"<div><button>Current theme: light</button></div>"`)

现在,如果您对组件进行了更改,这些更改将影响所有快照,则可以通过调用以下命令一次更新所有快照

npx wdio run wdio.conf.ts --updateSnapshots
# or
npx wdio run wdio.conf.ts -s

这使得维护您的测试变得更加容易。同样的方法也适用于所有其他类型的对象,例如 CSS 属性或元素的文本内容。它们都可以转换为快照,以简化断言并保持测试精简。这还可以通过将许多单个断言合并为一个来加快测试速度,例如

const elem = $('#alertBar')
await expect(elem).toHaveAttribute('data-alert')
await expect(elem).toHaveClassName('success')
await expect(elem).toHaveText('You logged into a secure area!')

现在变成一个

await expect($('#alertBar')).toMatchSnapshot()
/**
* stores the following into a snapshot file:
*
* <div data-alert="" id="flash" class="flash success">
* You logged into a secure area!
* <a href="#" class="close">×</a>
* </div>
*/

虽然获取 DOM 的快照可能是最突出的用例,但您可以获取所有类型的可序列化数据结构的快照,例如

// the visible content of an element
await expect($('elem').getText()).toMatchSnapshot()
// or of an serializable object
await expect($('elem').getCSSProperty('color')).toMatchSnapshot()

您可以在我们的快照指南中找到有关 DOM 和基于对象的快照的更多信息。

视觉快照

虽然获取元素结构及其属性的快照可能很棒且功能强大,但它有一个重要的警告:即使我们正在测试该元素是否具有名为 success 的类名,但这并不能保证该警报为绿色!

出于这些原因,视觉测试已成为一种非常流行的工具,因为它包含元素的渲染方式、颜色,并确保例如它不会被任何其他元素覆盖。获取视觉快照的工作方式非常相似,您可以

  • 获取整个屏幕的视觉快照
    await expect(browser).toMatchScreenSnapshot('partialPage')
  • 获取元素的视觉快照
    await expect($('#element-id')).toMatchElementSnapshot('firstButtonElement')
  • 获取整个页面的快照
    await expect(browser).toMatchFullPageSnapshot('fullPage')
  • 或获取包含页面选项卡功能的页面快照
    await expect(browser).toMatchTabbablePageSnapshot('check-tabbable')

WebdriverIO 会将这些视觉快照方便地存储在测试旁边的 __snapshots__ 目录中,与您的基于文本的快照一起存储。

虽然基于文本的快照测试内置于 WebdriverIO 中,但您必须安装一个服务以通过以下方式启用所有视觉快照功能

npm i --save-dev @wdio/visual-service

随着视觉测试模块的最新版本发布,我们为**移动原生应用程序快照测试**提供了进一步的改进。

移动原生应用程序快照测试

该模块现在支持移动原生应用程序的 toMatchElementSnapshottoMatchScreenSnapshot 匹配器。它会自动检测测试上下文(web、webview 或 native_app),以简化您的工作流程。

视觉服务的关键特性

使 WebdriverIO 的视觉测试独一无二的一些功能包括

  • 保存或比较屏幕/元素/全页面屏幕与基线
  • 在没有基线时自动创建基线
  • 屏蔽自定义区域,甚至在比较期间自动排除状态栏或工具栏(仅限移动设备)
  • 增加元素尺寸屏幕截图
  • 在网站比较期间隐藏文本
    • 提高稳定性并防止字体渲染不稳定
    • 仅关注网站的布局
  • 使用不同的比较方法和一组额外的匹配器,以便获得更易读的测试
  • 验证您的网站将如何支持使用键盘进行选项卡切换,另请参见浏览网站选项卡
  • 等等,请参阅服务方法选项

在我们的视觉文档中了解 WebdriverIO 的所有视觉测试功能,并加入我们在 Discord 上的👁️-visual-testing频道。

特别感谢@wswebcreation

我们要衷心感谢我们的核心维护者Wim Selleswdio-native-app-compare中的工作,这启发了此增强功能。他的贡献对于提高我们模块的功能至关重要。

感谢您持续的支持,我们期待您对这些新功能的反馈。

测试愉快!

WebdriverIO 团队

欢迎!我该如何帮助您?

WebdriverIO AI Copilot