动态搜索
另一种获得对象的方法就是动态搜索,使用动态搜索,就是用户自行使用 RFT 提供的搜索方法,从测试应用结构中的某个节点根据提供某些条件进行搜索获取对象。这个方法自由,灵活,而且能得到一些 ObjectMap 无法获取的对象。在我们的框架中,使用的就是这个方法。但这个方法在测试的应用对象结构复杂时,性能比较差。因为搜索将遍历起始节点下所有的对象层次结构。
这里提供的动态搜索的例子可以完成和使用 ObjectMap 完全相同的功能。不过限于篇幅,只提供了获得”View”按钮的例子。
代码 1. ViewButton.java:
package dynamicsearch; …… public class ViewButton extends GuiTestObject { public ViewButton( TestObject testObject ){ super( testObject ); } public static ViewButton getViewButton(){ //获取根测试对象,从该对象开始查找需要的对象 RootTestObject root = RootTestObject.getRootTestObject(); //通过匹配ViewButton的属性来找到该对象 TestObject to[] = root.find( RationalTestScript.atDescendant( ".class", ".Pagetab", ".name", "View" ) ); return new ViewButton(to[0]); } } |
代码 2. DynamicSearch.java
package TestScript; public void testMain(Object[] args) |
高效的对象缓存机制
我们想使用动态搜索,但又想有 ObjectMap 的性能优点,于是我们采用了一种高效的对象缓存机制来对动态搜索获取的对象进行缓存和管理,使动态搜索获取的对象可以做到只需要搜索一次,而不用再每次需要使用的时候都进行搜索,这样就减少了大量的搜索时间,提高了性能。同时,在对对象的管理上,该机制采用了类似 ObjectMap 的层次结构,相当于一种简化的 ObjectMap。
* 该缓存机制具有与 ObjectMap 类似的层次结构
* 在这个机制中,只有需要的对象才会被存储
* 如果应用的变化没有造成缓存中存储的对象层次之间的变化,不需要调整缓存部分的代码。
* 缓存是全局的,如果对象层次结构发生,对程序的修改将基本被限制在缓存这层代码中,不会造成整个框架和所有测试脚本需要修改的惨状。
该机制的实现并不复杂。
* 使用被测试应用的顶层窗口对象作为根对象存储。
* 把隶属于该窗口的对象作为根对象的成员变量存储 .
* 按照 ObjectMap 的层次顺序存储对象,下层的作为上层的成员变量。没有用到的对象层次可以忽略。
* 在所需该对象为 Null 的时候,getter() 方法调用动态搜索方法获取对象
* 当所需对象不为 Null 的时候,getter() 方法直接返回缓存中存储的对象。
这里将使用这种缓存机制实现刚才的例子,如果这个操作只被调用一次,那么缓存机制将不会与普通的动态搜索方法有区别。但如果这是一个被频繁调用的操作,那么缓存机制将体现出它的价值,极大的减少对象获取的时间。
建立一个名为 WordWindow 的对象存储所有 MS Word 2007 窗口的直属子对象。这些子对象也可存储属于他们的子对象。
代码 3. WordWindow.java
package appObject; …… //WordWindow类包含所有在Word窗口中要操作的子对象及该窗口本身 public class WordWindow { private GuiTestObject viewButton; private GuiTestObject homeButton; public GuiTestObject getViewButton(){ if(viewButton == null ){ RootTestObject root = RootTestObject.getRootTestObject(); //通过匹配ViewButton的属性来找到该对象 TestObject to[] = root.find( RationalTestScript.atDescendant( ".class", ".Pagetab", ".name", "View" ) ); return new GuiTestObject (to[0]); } return viewButton; } public GuiTestObject getHomeButton(){ if(homeButton == null ){ //通过匹配HomeButton的属性来找到该对象 RootTestObject root = RootTestObject.getRootTestObject(); TestObject to[] = root.find( RationalTestScript.atDescendant( ".class", ".Pagetab", ".name", "Home" ) ); return new GuiTestObject(to[0]); } return homeButton; } } |
CacheVer1.java: 使用缓存机制完成操作。