组件、端到端和移动测试的 DOM 和视觉快照测试简介
我们很高兴地宣布支持使用一组支持 WebdriverIO 提供的所有测试环境的通用原语的 DOM 和视觉快照测试。我们的愿景一直是提供一个全面、通用的测试工具,简化您的工作流程。此更新是朝着创建用于单元和视觉测试的“瑞士军刀”迈出的一步,满足跨平台的多样化需求,并将我们的支持扩展到原生移动应用程序,使您的测试流程更高效、更无缝。
在运行组件和单元测试、端到端测试以及移动 Web 测试时,DOM 和视觉快照原语都可供您使用。除此之外,相同的视觉快照原语也可用于原生移动应用程序测试。
如果您更喜欢视觉学习,我们还在我们的YouTube频道上发布了 WebdriverIO 教程
让我们深入了解这些强大的功能。
DOM 或对象快照
为了评估 DOM、大型对象或 UI 元素内容的状态,我们通常倾向于将值复制到我们的测试中,并在更改应用程序或组件的行为时手动更新它。
使用基于文本的快照,我们可以让 WebdriverIO 处理它。例如,假设我们要验证 React 组件在浏览器中的状态,我们可以执行以下操作
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
随着视觉测试模块的最新版本发布,我们为**移动原生应用程序快照测试**提供了进一步的改进。
移动原生应用程序快照测试
该模块现在支持移动原生应用程序的 toMatchElementSnapshot
和 toMatchScreenSnapshot
匹配器。它会自动检测测试上下文(web、webview 或 native_app),以简化您的工作流程。
视觉服务的关键特性
使 WebdriverIO 的视觉测试独一无二的一些功能包括
- 保存或比较屏幕/元素/全页面屏幕与基线
- 在没有基线时自动创建基线
- 屏蔽自定义区域,甚至在比较期间自动排除状态栏或工具栏(仅限移动设备)
- 增加元素尺寸屏幕截图
- 在网站比较期间隐藏文本以
- 提高稳定性并防止字体渲染不稳定
- 仅关注网站的布局
- 使用不同的比较方法和一组额外的匹配器,以便获得更易读的测试
- 验证您的网站将如何支持使用键盘进行选项卡切换,另请参见浏览网站选项卡
- 等等,请参阅服务和方法选项
在我们的视觉文档中了解 WebdriverIO 的所有视觉测试功能,并加入我们在 Discord 上的👁️-visual-testing频道。
特别感谢@wswebcreation
我们要衷心感谢我们的核心维护者Wim Selles在wdio-native-app-compare
中的工作,这启发了此增强功能。他的贡献对于提高我们模块的功能至关重要。
感谢您持续的支持,我们期待您对这些新功能的反馈。
测试愉快!
WebdriverIO 团队