图片比较一直是">自动化测试中的难点。虽然 Rational Functional Tester V8.0 专门提供了图片验证功能,但由于其是直接从屏幕上截图并逐一比较像素点,使得它的稳定性和可移植性都有待改善。本文采用了全新的图片获取方法和图片比较方法,绕过了 Rational Functional Tester 的缺陷,增强了脚本的可移植性和测试的稳定性,并扩展介绍了获取和比较尺寸较大的图片的方法。
问题描述
在自动化测试中,有时需要对图片进行验证,即判断图片以及图片的注释是否显示正确。在手动测试中,图片比较是很容易的,用肉眼识别即可。但在自动化测试中,图片比较却困难重重。Rational Functional Tester V8.0 专门提供了图片验证功能,用来实现图片比较的自动化。其实现原理是:直接从屏幕截图,然后将结果以无损压缩的 PNG 格式保存,之后再对图片的每一个像素点进行验证。但由于从屏幕截图与显示器直接关联,而不同测试机显示器的分辨率等设置可能并不相同,这就导致脚本的可移植性差。不仅如此,由于电磁波或其他的物理影响,同一台测试机在不同的测试中,显示器的某些像素点也可能产生些许的肉眼无法察觉的变化,导致同一台测试机上的测试也很不稳定,明明肉眼观察相同的图片,测试结果却显示失败。这使得测试效率低下,测试结果不能很好地反映软件的真实情况。
下面作者将结合自己工作中的实例,给出解决图片比较问题的全新方法。
获取图片
为了解决显示器截图的不稳定问题,本文的解决方案是:通过 GuiTestObject.getImage(R-ectangle rect, String fname) 方法,将需要比较的图片直接从内存中读取出来。其中 GuiTestObject 是被测软件中用来显示图片的控件对象。按文档中所写,该方法返回的是即将要显示在显示器上的图片。这样就隔离了图片与硬件的关联,增强了脚本的可移植性和测试的稳定性。
图 1. 显示图片控件
图 1 中用红色边框包围的就是被测程序中可被 RFT 识别的用来显示图片的控件,作者将其命名为 view。该控件由图片和灰色的画布两部分组成。我们必须只取其中的实际图片部分进行比较,而不能直接比较整个控件。因为虽然控件当中包含图片,但当分辨率改变时,图片和画布的相对大小将会改变(比如图片变大,灰色的画布部分变小),使得虽然图片显示正确,但由于整个控件的构图发生了变化,导致测试结果失败。而只取图片进行比较就不会有这种问题,因为虽然不同的分辨率下图片的大小不同,但那只是由于不同的分辨率使得像素的长宽发生了改变,并不会改变图片像素的数量和每个像素的颜色信息。
一般显示控件都会有相应的属性来说明其所包含图片的大小,在本例中,该属性为"preferredSize"。 view.getProperty("preferredSize") 方法会返回一个 Dimension 类型的变量,该变量的高和宽即为实际图片的高和宽。属性"locationOnScreen"可以获取该控件的坐标。综合这两个属性就可以使用方法 GuiTestObject.getImage(Rectangle rect, String fname) 获取实际的图片了。具体代码如下:
清单 1. 获取图片
Dimension d=(Dimension) view.getProperty("preferredSize");Point p=(Point)view.getProperty("locationOnScreen");Rectangle r=new Rectangle(p.x,p.y,d.width,d.height);BufferedImage input=view.getImage(r,"a");
最后用得到的内存中的图片 input 来进行图片的比较。