一种新的UI测试方法:视觉感知测试
什么是视觉测试
视觉测试(Visual Testing),主要检查软件用户界面(UI)是否正确显示给所有用户。它检查网页上的每个元素的形状、大小和位置是否符合预期,还检查这些元素是否在不同的设备和浏览器上是否兼容,不同的环境、不同的屏幕大小和其他影响UI显示的因素是否会影响产品的使用。视觉测试是解决 GUI 测试的一种测试手段。
为什么需要视觉测试
比如,我们开发了一个在线商城。第一次测试的时候所有的功能都能正常运行,但是当部署到另一个测试环境时,就有可能出现以下情况,这些都是因为界面布局 bug 导致用户无法正常使用,视觉测试就是用来发现这些界面布局导致的产品缺陷。
- 购买按钮忽然被一个弹框遮住,用户无法下单;
- 商品的详细描述文字互相堆叠错乱,导致用户无法正常阅读;
- 购物车没有正常悬浮在窗口的底部,无法查看加入了哪些商品;
- 电脑上能正常下单,但是在手机上却只显示了部分页面;
- 所有的图片无法正常加载等等。
文字堆叠示例:

样式缺失示例:

视觉测试和UI功能测试的区别
视觉测试和传统的ui功能测试不一样。ui测试是一个很广的范围,它既包括端对端的功能测试,又包括页面的布局测试,我们平时谈论的 ui 测试,更偏重于功能性测试,而视觉测试更偏重于页面布局测试。
功能测试确实能发现大部分主要的功能缺陷,甚至可以发现一些页面布局的缺陷,比如某些元素因为布局问题无法交互,某些元素缺失。 但是功能测试的问题在于它需要覆盖的路径太多,执行效率太慢,在迭代比较快的研发周期上,有些看似不太重要的特性不会去测试。而有些布局问题非常微小,但足以影响用户体验,功能测试无法做到。
视觉测试专注于页面布局和显示效果,可以精确到像素级的差异对比,当页面发生任何变化时,都能被视觉测试发现,大到足以影响功能使用的空间、小到让用户不舒服的运营文案的对比,都能被及时发现。
视觉测试尽量自动化
视觉测试最好采用自动化方式实现,它需要对每一个元素都要校验它的大小、形状和位置差异,有的差异非常微小,肉眼观察很困难。 手工的视觉测试更像是在玩大家来找茬的游戏,只是关卡的难度和关卡的数量都急剧上升,你得到的只有少量的成就感,更多的是沮丧和措手不及。
来看一个具体的例子。这是一张 python 官网的截图,这里有一个非常重要的产品缺陷,你能现在访问 python.org 官方,把这个重要的缺陷找出来吗?

这是正常的产品截图。经过对比可以发现:黄色的 Donate 按钮没有正常显示,这是 Python 基金会的收入来源,是一个很重要的产品功能,但是它可能被测试人员所忽略,平时的测试没有对它进行覆盖,从而影响的产品的收入。

视觉测试自动化工具
通常情况下,可以编写代码,对整套对照流程实现自动化,不会编写代码就只能使用在线的图像对照工具或者在测试软件中集成图像对照的服务。这些工具的使用方式都比较类似,首先打开服务网站:https://www.diffchecker.com/image-diff/,分别上传baseline 图片和实际图片。

在对比图片中,能直接看到图片中的哪些位置发生了变化,没有变化的元素全部都隐藏。

视觉测试工作流程
- 设置 baseline 对照组,表示产品本来应该的状态。
- 运行用例、通过截图等方式获取当前界面状态。
- 和 baseline 对比、生成报告,报告最好能直观看到页面差异。
- 更新 baseline。
视觉测试对于精准化测试的意义
- 视觉测试的主要目的是发现页面布局的缺陷
- 在视觉回归测试中,能立即发现界面哪些地方进行了修改。
我是九柄,公众号【 九柄 】,分享软件测试文章、面试、教程资料,欢迎来看看。
一种新的UI测试方法:视觉感知测试的更多相关文章
- 使用Minifly打造基于视觉感知的跟踪无人机
前言:无人机和人工智能现在是非常热门的话题,将两者结合起来是一个比较好的创意,本文介绍一种可行的解决方案来实现基于视觉感知的跟踪无人机.从零开始搭建无人机系统工作量和难度(以及钱)都是非常大的,所以在 ...
- iOS编程实战 — 新的UI范式
iOS 7给苹果设备带来了全新的用户界面(UI).iOS 7在UI上的变化是自其诞生以来最大的.iOS 7专注于三个重要的特点:清晰.依从和层次.理解这三个特点很重要,因为这有助于设计跟原生的系统内置 ...
- Unity3D学习(五):实现一个简单的视觉感知
前言 在很多第一人称或者第三人称射击游戏的单人模式中,玩家的乐趣往往来源于和各式各样的AI敌人的战斗.而战斗的爆发很多时候是因为这些AI在"看见"玩家后就会立即做出反应,比如开火. ...
- springboot之swagger快速启动(新的ui)
springboot之swagger快速启动(新的ui) 功能点: 集成swagger前端接口文档 Swagger 整合 zuul 智能列表 无缝集成 knife4j 前端文档 支持 v0.1.2RE ...
- 新的颜色对比度算法-感知对比度算法APCA
目录 对比度 在控制台查看 插件或网站 感知对比度算法(APCA) APCA Math 原理 js 实现的 SAPC 最后 灵感的源泉来源于不断的接受新鲜事物. Chrome 89 新功能一览,性能提 ...
- CVPR2021| 继SE,CBAM后的一种新的注意力机制Coordinate Attention
前言: 最近几年,注意力机制用来提升模型性能有比较好的表现,大家都用得很舒服.本文将介绍一种新提出的坐标注意力机制,这种机制解决了SE,CBAM上存在的一些问题,产生了更好的效果,而使用与SE,CBA ...
- 发表在 Science 上的一种新聚类算法
今年 6 月份,Alex Rodriguez 和 Alessandro Laio 在 Science 上发表了一篇名为<Clustering by fast search and find of ...
- javascript一种新的对象创建方式-Object.create()
1.Object.create() 是什么? Object.create(proto [, propertiesObject ]) 是E5中提出的一种新的对象创建方式,第一个参数是要继承的原型,如果不 ...
- 二十八、带给我们一种新的编码思路——EFW框架CS系统开发中的MVC模式探讨
回<[开源]EFW框架系列文章索引> EFW框架源代码下载V1.3:http://pan.baidu.com/s/1c0dADO0 EFW框架实例源代码下载:http://p ...
随机推荐
- 手把手教你在Linux中快速检测端口的 3 个小技巧
一个执着于技术的公众号 前言 无论是要解决网络连接问题还是配置防火墙,第一件事是要检查系统实际打开了哪些端口. 本文介绍了几种快速查找 Linux 系统上哪些端口向外部开放的方法. 什么是开放端口 监 ...
- Linux服务器安全加固10条建议
以下是服务器安全加固的步骤,本文以腾讯云的CentOS7.7版本为例来介绍,如果你使用的是秘钥登录服务器1-5步骤可以跳过. 设置复杂密码 服务器设置大写.小写.特殊字符.数字组成的12-16位的复杂 ...
- PowerJob高级特效-容器部署完整教程
介绍 powerjob提供了容器功能,用来做一些灵活的任务处理.这里容器为 JVM 级容器,而不是操作系统级容器(Docker).(至于为什么取"容器"这个有歧义的名字是因为作者没 ...
- 使用Spring MockMVC对controller做单元测试
1.对单一controller做测试. import org.junit.Before; import org.junit.Test; import org.springframework.beans ...
- 2022年5月11日,NBMiner发布了41.3版本,在内核中加入了100%LHR解锁器,从此NVIDIA的显卡再无锁卡一说
2022年5月11日,NBMiner发布NBMiner_41.3版本,主要提升了稳定性. 2022年5月8日,NBMiner发布NBMiner_41.0版本,在最新的内核 ...
- python+pytest接口自动化(16)-接口自动化项目中日志的使用 (使用loguru模块)
通过上篇文章日志管理模块loguru简介,我们已经知道了loguru日志记录模块的简单使用.在自动化测试项目中,一般都需要通过记录日志的方式来确定项目运行的状态及结果,以方便定位问题. 这篇文章我们使 ...
- 最佳案例 | 游戏知几 AI 助手的云原生容器化之路
作者 张路,运营开发专家工程师,现负责游戏知几 AI 助手后台架构设计和优化工作. 游戏知几 随着业务不断的拓展,游戏知几AI智能问答机器人业务已经覆盖了自研游戏.二方.海外的多款游戏.游戏知几研发团 ...
- MySql笔记Ⅱ
MySql笔记2: part3:(table相关的操作) 数据的增删改 create table t1( id int primary key auto_increment, username cha ...
- 很好用的vscode 插件 Open PHP/HTML/JS In Browser 让php文件直接在浏览器打开
p { font-size: 25px } <body> <h1>安装插件</h1> <img src="https://img2020.cnblo ...
- MVC - Request对象的主要方法
MVC - Request对象的主要方法 setAttribute(String name,Object):设置名字为name的request的参数值 getAttribute(String name ...