Cypress中的视觉测试
你将学到
- 功能测试与视觉测试的区别
- 如何使用视觉测试插件
- 视觉测试的最佳实践
简介
Cypress提供 了多种测试解决方案,包括:
虽然许多解决方案如Test Replay、Cypress Accessibility和UI Coverage提供了应用程序的可视化展示,但拥有自动化方法来确保应用程序视觉效果符合预期至关重要。这就是视觉测试的作用。
视觉测试是一种专注于应用程序外观的测试类型。它确保应用程序在更改后对用户看起来保持一致。
- 端到端测试
- 组件测试
it('completes todo', () => {
cy.visit('/') // opens TodoMVC running at "baseUrl"
cy.get('.new-todo').type('write tests{enter}')
cy.contains('.todo-list li', 'write tests').find('.toggle').check()
cy.contains('.todo-list li', 'write tests').should('have.class', 'completed')
})
it('completes todo', () => {
cy.mount(<Todos />)
cy.get('.new-todo').type('write tests{enter}')
cy.contains('.todo-list li', 'write tests').find('.toggle').check()
cy.contains('.todo-list li', 'write tests').should('have.class', 'completed')
})
技术上你可以编写功能测试,使用have.css
断言来验证CSS属性,但这些测试可能很快变得繁琐且难以维护,尤其是当视觉样式依赖大量CSS时。
cy.get('.completed').should('have.css', 'text-decoration', 'line-through')
cy.get('.completed').should('have.css', 'color', 'rgb(217,217,217)')
你的视觉样式可能不仅依赖CSS,还可能涉及SVG、图像渲染或Canvas绘制。幸运的是,Cypress提供了 一个稳定平台,可以集成插件来进行视觉测试。
这类插件通常会对整个应用程序或特定元素进行截图,然后与之前批准的基准图像进行比较。如果图像相同(在设定的像素容差范围内),则认为应用程序对用户看起来一致。如果有差异,则需要调查DOM布局、字体、颜色或其他视觉属性的变化。
例如,可以使用cypress-plugin-snapshots插件捕获以下视觉回归:
.todo-list li.completed label {
color: #d9d9d9;
/* removed the line-through */
}
it('completes todo', () => {
cy.visit('/')
cy.get('.new-todo').type('write tests{enter}')
cy.contains('.todo-list li', 'write tests').find('.toggle').check()
cy.contains('.todo-list li', 'write tests').should('have.class', 'completed')
// run 'npm install cypress-plugin-snapshots --save'
// capture the element screenshot and
// compare to the baseline image
cy.get('.todoapp').toMatchImageSnapshot({
imageConfig: {
threshold: 0.001,
},
})
})
这个开源插件在像素差异超过阈值时并排显示基准图像(预期结果)和当前图像(实际结果);注意基准图像中的标签文本有删除线,而新图像中没有。

像大多数图像比较工具一样,该插件在鼠标悬停时还会显示差异视图:

工具
在插件的视觉测试部分列出了多个开源插件,以下是一些基于Cypress开发的商业视 觉测试解决方案。
Applitools
参见Applitools官方文档和我们的教程。
与Applitools的第二次联合网络研讨会,重点介绍组件测试
Percy
Cypress 真实世界应用(RWA) 使用Cypress Percy插件提供的cy.percySnapshot()
命令,在端到端测试中捕获用户旅程的视觉快照。
查看Real World App测试套件,了解Percy和Cypress的实际应用。
Happo
Chromatic
Chromatic利用你现有的Cypress设置——配置、模拟和测试——实现对应用程序UI的视觉测试。安装Chromatic插件后,Chromatic会在Cypress测试运行时捕获UI的存档。
参见Chromatic官方文档和他们的博客。
Argos
Argos与你现有的Cypress设置——配置、模拟和测试——无缝集成,实现对应用程序UI的视觉测试。设置Argos后,它会在Cypress测试运行期间捕获并分析截图,以检测视觉变化。
查看Argos官方文档获取设置指南和最佳实践。
Wopee.io
Wopee.io与Cypress无缝集成,以增强测试覆盖率,加快维护速度,并确保更稳定的测试运行。Wopee.io旨在实现自主视觉测试,让你轻松将视觉验证集成到现有的Cypress测试中,增加额外的质量保证层。
参见Wopee.io官方文档、我们的网络研讨会及其博客和网络研讨会。
最佳实践
视觉测试有一些通用的最佳实践。
识别视觉测试的需求
验证样式属性的断言
cy.get('.completed').should('have.css', 'text-decoration', 'line-through')
.and('have.css', 'color', 'rgb(217,217,217)')
cy.get('.user-info').should('have.css', 'display', 'none')
...
如果你的端到端测试中充满了检查可见性、颜色和其他样式属性的断言,可能是时候开始使用视觉差异来验证页面外观了。
DOM状态
最佳实践: 在确认页面已完成更改后拍摄快照。
例如,如果快照命令是cy.mySnapshotCommand
:
错误用法
// 应用程序需要时间添加新项目,
// 有时会在新项目出现之前拍摄快照
cy.get('.new-todo').type('write tests{enter}')
cy.mySnapshotCommand()
正确用法
// 使用功能断言确保
// 应用程序已重新渲染页面
cy.get('.new-todo').type('write tests{enter}')
cy.contains('.todo-list li', 'write tests')
// 很好,新项目已显示,
// 现在可以拍摄快照
cy.mySnapshotCommand()
时间戳
最佳实践: 控制被测应用程序内部的时间戳。
下面我们使用cy.clock()将操作系统时间固定为2018年1月1日
,以确保所有显示日期和时间的图像匹配。
const now = new Date(2018, 1, 1)
cy.clock(now)
// ... 测试
cy.mySnapshotCommand()
应用程序状态
最佳实践: 使用cy.fixture()和网络模拟来设置应用程序状态。
下面我们使用cy.intercept()来存根 网络调用,为每个XHR请求返回相同的响应数据。这确保了我们应用程序图像中显示的数据不会变化。
cy.intercept('/api/items', { fixture: 'items' }).as('getItems')
// ... 操作
cy.wait('@getItems')
cy.mySnapshotCommand()
视觉差异元素
最佳实践: 使用视觉差异检查单个DOM元素,而不是整个页面。
针对特定DOM元素有助于避免组件"X"的视觉变化破坏其他无关组件的测试。
组件测试
最佳实践: 使用组件测试来测试单个组件的功能,同时进行端到端和视觉测试。
另请参阅
- After Screenshot API
- cy.screenshot()
- Cypress.Screenshot
- 插件
- 视觉测试插件
- Node Events概述
- 真实世界应用(RWA) 是一个全栈示例应用程序,展示了在实用和现实场景中使用Cypress的最佳实践和可扩展策略。
- 阅读博客文章调试不稳定的视觉回归测试