代码语言:txt复制
提起ui自动化大家首先想到的就是基于控件的自动化,比如常见的xpath、id、css选择器等手段进行元素定位并进行结果判断。但是在实际应用中,无论是web端还是移动端,仍有很多时候需要根据页面内容、页面中的图像进行定位及判定,是这些手段所达不到的,这里我们来介绍一下关于图像识别在测试中的应用。
代码语言:txt复制 在具体讲解之前,先介绍一下图像识别在测试中能够想到的引用场景:
- 测试过程中,通过对待测软件进行屏幕截图,采用图像识别算法识别截图中是否包含预定义的可操作控件,如果存在,则触发控制指令,也就达到了图像识别引导测试过程的目的。- 测试结果的验证,通过对待测软件的界面进行截图操作,利用图像识别技术将截图与期望的结果进行匹配,从而自动获取测试结果。- 通过图像识别对比来进行性能测试,比如app测试中常见的响应时间的测试。 一、原理
Sikuli脚本是由jython通过图像识别的方式来模拟键盘和鼠标事件,从而实现ui层面的自动化测试。Sikuli脚本的核心是一个java库 ,主要由两部分组成(见上图):
代码语言:txt复制 java.awt.Robot部分主要是将键盘和鼠标事件传送给指定的位置,具体的位置是由c 引擎(基于opencv模块)通过脚本中的目标图片去屏幕上搜索并定位。C 引擎与java的JNI链接并且进行编译来适应不同的平台。在java的上层则是一个简单的应用层,主要用于开发自动化脚本,这层给最终用户提供了一套简单易用的命令。
二、函数介绍
1.find(x)
代码语言:txt复制 在屏幕上找到相对应的图片,比如选定一个手机。
示例代码:
代码语言:txt复制2.findall(x)
代码语言:txt复制 在屏幕上找到所有的相同图片x,比如可以关注多个手机(一次性把所有的图片的坐标选定,如果选定后再刷新桌面背景有可能出现之前的坐标和之前的功能点对应不上,达不到测试效果)。
示例代码:
代码语言:txt复制3.wait(x,10)
代码语言:txt复制 等待图片x在屏幕上或者指定的区域中出现,超时时间设为10秒。
示例代码:
代码语言:txt复制4.waitVanish(x,10)
代码语言:txt复制 等待屏幕上或者指定区域中给定的gui组件消失,最长等待10秒(最好设置时间)。
示例代码:
代码语言:txt复制5.exists(x)
代码语言:txt复制 在屏幕上或者指定区域中查找指定的GUI组件是否存在,若找不到该组件,就返回none,不抛异常,同时可以设置超时时间。
示例代码:
代码语言:txt复制6.click(x)
代码语言:txt复制 在屏幕上或指定区域中左键单击匹配度最佳的GUI组件。
代码语言:txt复制示例代码
代码语言:txt复制7.dubleclick(x)
代码语言:txt复制 在屏幕上或指定区域中双击匹配度最佳的GUI组件。
示例代码:
代码语言:txt复制8.rightclick()
代码语言:txt复制 在屏幕上或指定区域中右击匹配度最佳的GUI组件。
代码语言:txt复制示例代码:
代码语言:txt复制9.hover(x)
代码语言:txt复制 将鼠标指针移动到匹配度最佳的GUI组件。
代码语言:txt复制示例代码:
代码语言:txt复制10.dragDrop(x,y)
代码语言:txt复制 将图片x拖拽到图片y上。
代码语言:txt复制 示例代码:
代码语言:txt复制11.type(x,“text”)
代码语言:txt复制 给选定的焦点输入内容。
代码语言:txt复制 示例代码:
代码语言:txt复制12.paste(x,“text”)
代码语言:txt复制 给选定的焦点粘贴内容。
代码语言:txt复制示例代码:
三、代码介绍
代码语言:txt复制 下方图片是一个具体的demo,代码介绍则可参考:
http://www.sikuli.org/productivity.html
四、优缺点
优点:
介绍到这里会有人问,有了webdriver等ui自动化后为什么还要用图像识别呢?我认为主要有以下这几点:
1、代码简单易懂,简单到什么程度呢?可以说会截图就可以进行自动化测试。
2、一些游戏或者一些特殊应用的ui控件比较难以识别,然而通过图像识别却可以轻易找到对应的元素。
3、代码的学习成本比较低,常用的函数已经封装完毕,并且简单易懂。
4、工具开源可以进行二次开发,扩展性更好。
5、可以识别类似flash这样不能通过识别控件来进行自动化测试的项目。
缺点:
1、屏幕不能有遮挡,因为sikuli需要在当前桌面识别对应的目标并进行操作,如果桌面有遮挡就会导致对应的元素找不到。
2、如果代码换一个显示屏进行测试就要重新进行截图,因为之前所有的截图分辨率已经不适应当前界面。
3、不能在后台进行测试,必须前台运行。
<br style="box-sizing: border-box;"/>