通过缓存对象路径的方式提高RFT的对象识别效率

发表于:2012-10-17 10:30

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:dreamever    来源:51Testing软件测试博客

  又是漫漫长夜,无心睡眠……这次文章是技术总结,不是随想,所以省去开头和暖场,直接切入正题。本文档对于如何使用RFT+XPATH提高自动化测试的执行效率提供了一种新的思路,就是缓存对象路径,(PS:没用过RFT做自动化测试的同学可以忽略了 ,用watir的同学也可以忽略了。)

  界面对象识别及维护的费效比是UI自动化测试永远的话题

  UI层的自动化测试,提高脚本的执行效率是永远的主题,我们必须把一轮脚本的执行时间控制在可接受的范围内,当脚本的总体执行时间很长时,我们就需要对其进行优化,优化的方法无非是三种,1、优化用例,减少无效用例的个数;2、提高脚本识别UI对象的效率;3、分布式执行。本文介绍的方法属于第二种,提高脚本识别UI对象的效率。

  什么是RFT

  RFT是IBM的一款自动化测试工具,它的作用和QTP类似,使用JAVA作为脚本语言,ECLIPSE作为IDE,优雅并且强大。RFT识别对象的核心方法是RootTestObject的find方法。我们做自动化测试的时候,通过对FIND方法的封装实现了自己的对象识别框架。但是find方法的执行效率问题一直是我的心病。之前的情况是查找对象时,执行一次find方法至少要4-6秒的时间,几百个用例执行下来执行时间就让人无法忍受了,十几个小时……只能晚上跑脚本,早上来看结果,真赶到上午发版的时候,根本指望不上自动化测试能帮上什么忙,所以必须要想办法缩短脚本执行的总体时间,提高对象的识别效率。

  什么是XPATH

  XPATH是一种XML的查询语言。简洁,高效。在IBM的开发者社区论坛里,有专门的一篇文章讲解如何结合RFT+XPATH来实现动态识别对象,很赞。这里给出文章的链接:《使用 XPath 在 Rational Functional Tester 中动态识别对象》,作者刘哲,段雪飞,邢静。在此表示感谢并崇拜一下。另外多说一下,IBM的开发者社区真的很有料,他们的文档库里关于自动化测试的文章建议大家通读,保证你获益匪浅。

  XPATH识别对象的效率明显优于find方法,为什么?原因在于XPATH查找对象是基于某个对象的具体路径,而find方法是动态查找,也就是全局查找,这样遍历的对象多,必然就慢。举一个xpath的例子,来源于刚才的那篇文章,对于对象,使用XPATH来查找时路径可能是:"org.eclipse.swt.widgets.Shell[@captionText='Hello']/org.eclipse.swt.widgets.Button[@text='OK']"),而使用rft的find方法如果想实现同样的效果,就只能用atChild来拼了。写过RFT脚本的同学应该都有体会,事实上,如果在xpath中不使用路径而直接传入/::desander[@captionText='Hello'],那么他的执行效率和find的全局查找是类似的。

  问题及解决方案

  但是XPATH虽然快,可是仍然有缺点,那就是路径的维护问题。在一个自动化测试工程中,我们可能会使用到近百个测试对象,我们当然可以把每个对象的XPATH路径存到文本文件里,但问题是,如果程序的页面结构发生变化了,怎么办,这么多的缓存路径改起来不是闹着玩的,而且排查错误也不容易。所以我一直在寻找一种方法,能结合RFT动态识别和XPATH效率快两个优点,并且维护简单,后来就有了这个想法:把一个测试对象的父对象的class属性依次读取出来,拼成该对象的一个路径并写入到缓存文件中,当脚本在识别对象时,首先从缓存文件中把路径读取出来,并传递给XPATH去识别,如果对象能识别到,则执行操作;如果识别不到,则重新执行find方法进行识别,并把识别到的对象的路径重新更新到缓存路径中,如果find方法也找不到对象,就返回null,此时就需要人工介入排查识别的原因了。这种做法就是我标题中提到缓存对象路径的作法。

  关于缓存文件的存储格式,我采用的策略是为每一个UI层的测试对象分配唯一个的objectID作为标识。规则是脚本名称 + object_id + objecg_value。其中object_id和object_value是你在识别测试对象时使用的属性。写过RFT脚本的同学应该都懂,不懂的就给我发私信吧,因为也不是一句两句能解释清楚的,毕竟这不是一篇教程,大家见谅;

  缓存对象路径的做法,其实核心就是两点:

  1、在识别测试对象时,永远先从缓存文件中读取对象路径并由XPATH识别;

  2、当路径失效或者不存在时,由自动化测试代码自动更新路径,不然想自己手写XPATH路径的同学您最好先考虑清楚。

  以下是几个核心代码的实现,供大家参考。(PS:想要直接拷代码的同学可以忽略下面的内容了,因为你没有这些代码底层的支持代码,拷过去也没用的)

  通过递归读取对象路径的方法:

private void addPropertyToCatch(TestObject to, StringBuffer str) {
  Hashtable<Object, Object> p = to.getProperties();
  String _class = p.get(".class").toString();

  str.append("child::").append(_class);
  if (_class.contains("Html.TR")) {
   int rowIndex = this.getHtmlTRIndex(to);
   str.append("[").append(rowIndex + 1).append("]_@/@");
  } else if (_class.contains("Html.TD")) {

   // 在IE的document模型中,所有的索引都是从1开始的
   int index = this.getHtmlTDIndex(to);
   str.append("[").append(index + 1).append("]_@/@");
  } else {
   int classIndex = this.getHtmlTOIndex(to);
   if (classIndex == -1) {
    if (_class.contains("Html.HtmlDocument") && p.containsKey(".title")) {
     String title = p.get(".title").toString();
     str.append("[contains(@_").append(".title,'").append(title)
       .append("')]");
    }
    str.append("_@/@");
   } else {
    str.append("[").append(classIndex + 1).append("]").append(
      "_@/@");
   }
  }

 }

31/3123>
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号