RFT的两种校验方法之介绍和比较
我们在做自动化测试时,会需要验证页面上某些值是否是我们所期望的预期值,我们把它称为校验点。RFT有两种校验点:一种称为静态的校验点,另一种成为动态的校验点。
首先,介绍一下静态校验点,静态校验点的方法很简单,和原来我们用ROBOT时差不多,是在代码里写好校验点所在的窗口,校验点控键的类型和校验点在代码中的名称。然后让工具通过这些条件到网页上找到该校验点,然后再比较校验点里的值是否和我们预期的值相等。
其次,再来介绍动态校验点,动态校验点的方法相对于上述方法来说,要复杂多了。它的思想是这样的,把验证点的预期值和验证点的描述放在两个资源文件里,当调用这个验证方法的时候,会把页面上的包含所有验证点的控键容器,作为一个参数传到方法里,然后这个方法通过调用资源文件,搜索容器中符合验证点描述的控键,再把其值取出和预期值进行比较。
最后,这两种方法之比较,见下表:
| 静态测试方法 | 动态测试方法 |
预期值 | 硬编码于源程序中 | 配置在一个单独的文件中 |
被测试控件 | 需要一个个的抓取到scrīpt explorer中 | 配置在一个单独的文件中 |
校验代码 | 非常冗长,代码行和校验点数量成正比 | 非常简短,而且随着校验点增加而不变 |
维护性 | 需要在编译前修改源程序,而且经常需要维护scrīpt explorer | 只需要修改两个配置文件,不需要重新编译,几乎不需要维护scrīpt explorer |
重用性 | 几乎没有重用性,对于新增加的校验点,需要添加新的程序段 | 重用性非常高,不需要对新增的校验点不需要编写任何新的代码 |
性能 | 性能非常好 | 性能中等,因为遍历需要消耗时间 |
在前面提到,在动态的测试框架下,如果需要进行回归测试,或者增加/减少被测试控件,只需要修改两个配置文件并且重新运行即可。在这个过程中,预期值、测试过程和被测试对象之间的耦合被大量减少,带来的是代码可读性和可维护性的提高。然而,该方法也是以损失一部分性能为代价的,因为对象的动态识别需要至少两次遍历tabContent内部的所有对象,这就损失了一些效率。幸运的是,对于大多数基于eclipse的被测试程序,根据实践经验用户通常感觉不到这方面性能的问题。
动态的校验点测试的另外一个巨大的潜力在于,它有潜力发展成为一种校验点测试的框架。测试人员使用自动化测试工具来进行测试,其本质目的是为了能够减少手工重复点击和校验,所以测试人员书写的代码脚本越少越少。将测试人员关注的业务部分单独配置出来,而将他们不熟悉的部分封装在一个框架中,会大大提高测试工作的有效性。而本文提供的动态校验点测试正是在这个方面做出了一定的探索。在这个基础上,再增加配置文件的管理、多种控件/相对位置的识别,再辅之于输入输出的接口,它就可能是一个通用性很强的RFT测试框架。
附:以CWT员工管理为例,说明两种种验证点方法的核心代码
1.静态验证点判断方法:
boolean result=staffpw.equals(text_staffPassword2().getText());//判断字符串是否等于预期值
String context="The value of textfield ="+staffpw;
RationalTestscrīpt.logTestResult(context,result);//输出测试的结果
3.动态验证点判断方法:
//该类负责主要的校验流程和关键参数的传入
public class PanelVerifier {
private TestObject tabContent = null; //控件容器的引用
private String dataPath = null; //预期值文件和控件定义文件的存储位置
public PanelVerifier(String dataPath, TestObject tabContent) {
this.tabContent = tabContent;
this.dataPath = dataPath;
}
private List readProperties() throws Exception {
/**
*然后,添加方法readProperties来读取配置文件。readProperties方法读
*取预期值文件和控件定义配置文件,将这些读取的值封装在一个List中,List
*的每个元素都是ObjDef的实例。每个ObjDef对应于一个被测试的控件对象,其中的各种属性值都来自于配置文件。
*/
Map propertiesMap=readAllProperties();
List lst = new ArrayList();
try {
Set set = propertiesMap.keySet();
Iterator iter = set.iterator();
while (iter.hasNext()){
Object obj1 = iter.next();
System.out.println(obj1 + "::" + propertiesMap.get(obj1));
String[] str = propertiesMap.get(obj1).toString().split(",");
ObjDef ōbj = new ObjDef();
obj.setInput(str[0]);
obj.setLabel(str[1]);
obj.setPos(str[2]);
obj.setType(str[3]);
lst.add(obj);
}
} catch(Exception e) {
e.printStackTrace();
}
return lst;
}
public Map readAllProperties() throws Exception {
Properties p = new Properties();
Map propertiesMap = new HashMap();
File file = new File(dataPath + IConstant.IDSFILE);
p.load(new FileInputStream(file));
loadProperties(p, propertiesMap);//propertiesMap:{staffEmail=seasy@etraveltek.com, staffName=seasy, staffRPW=123, staffPW=123}
System.out.println(propertiesMap);
file = new File(dataPath + IConstant.OBJECTSFIlE);
p.load(new FileInputStream(file));
loadProperties(p, propertiesMap);//propertiesMap:{staffEmail=seasy@etraveltek.com,.tag,Text, staffName=seasy,.tag,Text, staffRPW=123,.tag,Text, staffPW=123,.tag,Text}
System.out.println(propertiesMap);
return propertiesMap;
}
private void loadProperties(Properties p, Map propertiesMap) {
Set pSet = p.keySet();
Iterator iter = pSet.iterator();
while (iter.hasNext()) {
Object key = iter.next();
String value = p.getProperty(key.toString());
setMapValue(propertiesMap, key, value);
}
}
private void setMapValue(Map map, Object key, Object value) {
Object beforeValue = map.get(key);
if (beforeValue == null) {
map.put(key, value);
} else {
map.put(key, beforeValue.toString() + "," + value.toString());
}
}
/**
*接下来,为类PanelVerifier增加一个filterSubitems方法,该方法能够 在一个被测试对象内部寻找属性符合预期的子对象。比如
* filterSubitems(tabcontent, "text","Name"),就是在
* tabcontent的所有子对象中寻找符合属性text等于Name的子对象。
*/
private List filterSubitems(ExtTestObject testobject, String propertyname,
Object propertyvalue,Object lablevalue) {
TestObject[] children = testobject.getTestObject().getChildren();
ArrayList list = new ArrayList();
for (int i = 0; i < children.length; i++) { //循环遍历所有内部的被测试对象
TestObject subitem = children[i];
// System.out.println(subitem.getProperties());
ExtTestObject eto = new ExtTestObject(subitem);
try {
Object value1 = subitem.getProperty(propertyname);
Object value2 = subitem.getProperty(".name");
if (value1 != null && value1.equals(propertyvalue) && value2 != null && value2.equals(lablevalue) ) { //判断对象是否符合要求
list.add(eto);
}
} catch (Exception e) {
}
list.addAll(filterSubitems(eto, propertyname, propertyvalue,lablevalue));
}
return list;
}
public void verify() throws Exception {
List expectvalue = readProperties();
for (int i = 0; i <expectvalue.size(); i++)
{
ObjDef ōbj = (ObjDef) expectvalue.get(i);
List factvalue = filterSubitems(new ExtTestObject(tabContent),obj.getPos(),obj.getType(),obj.getLabel());
boolean flag=false;
String value = "";
for (int j = 0; j < factvalue.size(); j++)
{
ExtTestObject eto = (ExtTestObject) factvalue.get(j);
value = (String) eto.getTestObject().getTestData("text")
.getProperty("data");
boolean result = value.equals(obj.getInput());
if (result)
{
RationalTestscrīpt.logTestResult(