<%@ page contentType="text/html; charset=gb2312"%> RFT与Spring结合进行自动化脚本开发之一
网站公告:   ◆北天JAVA技术网热情为java爱好者服务,本网内容包括JAVA(JSP、servlet、EJB、webservice、j2ee、javabean、应用服务器、JavaScript),数据库(MYSQL、SQL Server、Sybase、Oracle、DB2、数据库综合知识),设计研究(设计模式、Struts、Spring、Hibernate、设计框架、设计综合知识),WEB2.0新技术(主要介绍AJAX),以及各种技术的入门、实例、例子等等,欢迎各位多来坐坐!◆  诚邀各位JAVA爱好者加盟!◆  本网站内容丰富,更新快,保证每周20篇以上!  
加入收藏
设为首页
联系站长
承接项目
  相关资源:网站首页 | 免费培训学院 | 技术论坛 | JAVA聊天室 | 作家专栏 | 开发工具 | 认证考试 | 会员俱乐部
  JAVA技术初学者园地 | jsp与servlet | javascript | Java源代码 | EJB | web service | 应用服务器 | JAVA综合知识
  设计研究设计模式 | 设计框架 | Struts | Spring | Hibernate | 开源项目 | 面向对象设计 | 设计综合知识
  数 据 库MYSQL | SQL Server | Sybase | Oracle | DB2 | Informix | Access | 数据库综合知识
  其他资源:AJAX新技术 | 网站开发 | ERP软件 | OA办公软件 | 商业智能BI | 开发综合知识 | 承接项目 | 项目试用

 
 
RFT与Spring结合进行自动化脚本开发之一
     发布者: 发布时间:2007-10-03
  Spring具有强大的功能:Ioc,可以实现在xml中把一个测试对象注入到另一个测试对象中,再加上可以利用RFT的find方法可以把spring的配置文件配置成一张RFT测试对象地图。目前,大部分自动化脚本开发者利用RFT的测试对象地图管理测试脚本的测试对象,RFT的测试对象地图有两种类型:公有测试对象地图和私有测试对象地图。

  (1)大部分脚本采用的都是私有测试对象地图,如果被测试的程序顶层对象发生变化,这样每个脚本关联的测试对象地图都要进行修改,之所以这样,有一个原因:在RFT中测试对象地图不能够继承(仅仅可以合并),如果两个测试对象地图之间可以进行继承,这样把公用的测试对象放在父测试对象地图中,其他的测试对象地图继承这个公用的测试对象地图(同时继承公有的测试对象),如果被测试程序顶层框架发生变化,仅仅只修改父测试对象地图就可以了,但是目前RFT中不能实现(据我了解)。

  (2)RFT中还有一种类型的测试对象地图是公有的测试对象地图,公有的测试对象地图可以实现公用的测试对象重复使用,如果测试对象是一模一样的,RFT在公有的测试对象地图中只保留此测试对象的一个实例,但是把多个测试对象都插入到一个测试对象地图中,同样又面临着难以管理的困难。

  (3)另外,RFT中的测试对象地图与脚本紧紧的耦合,如果程序即使发生很小的变动,也要更新测试对象地图,修改脚本等等。

  (4)一个spring配置文件可以被另一个spring文件import进来。这样可以把公有的测试对象放在一个spring配置文件中,然后有其他的spring配置文件进行导入,可以实现测试对象地图(spring的配置文件)的继承。另外,在spring的配置文件中,可以注入一个对象的属性,这样可以人工的更改这个测试对象的父框架,另外可以可以注入测试对象的识别属性,这样可以进行人为的进行测试对象识别属性的更改(这样可以更好的应对被测试程序的变化)。

  例如:

  xml 代码
  
<!--从classpath(类路径)中导入base-test-object-map.xml文件 可以使用base-test-object-map.xml文件中定义的bean-->
<!--导入时候要包含完整的包名-->
<import resource="classpath:pkg/base-test-object-map.xml"/>

<!--设置待查找对象的识别属性 格式:propertyName-propertyValue-->
<property name="objectProperties">
<list>
<!--属性名称和属性精确匹配用=-->
<!--属性名称和属性用正则表达式匹配用:-->
<value>.class=Html.FORMvalue> 然后是怎么使用spring配置文件中的测试对象
<value>.name:.*Formvalue>
list>
property>

<!--设置从什么对象开始查找 注入父测试对象-->
<!--browserTestObject 引用的是base-test-object-map.xml文件中已经定义的bean-->
<property name="parentTestObject">
<ref bean="browserTestObject"/>
property>

  在脚本中引用测试对象通过如下语句:

  java 代码

TextGuiTestObject text_userName = new TextGuiTestObject((TestObject)context.getBean("userNameText"));
text_userName.setText("system");

  (5)采用spring管理测试对象,也不是说一劳永逸的,如果被测试程序发生变化,避免不了的也要修改spring配置文件。但是,至少比RFT管理测试对象地图的修改量要小的多。

  (6)采用spring管理测试对象也有以下缺点:

   (1)需要测试脚本开发者有比较高的编程技能(熟悉springIoc基本配置和对RFT API比较熟悉)

   (2)被测试程序结构规范,最好每个HTML元素都有其名字,还有每次修改程序,如果HTML元素名称能不修改最后就不修改(RFT可以通过组件名称查找对象)还有就是按钮上面的文本,采用RFT管理测试对象地图也有此要求。

   (3)要求对被测程序的组件结构有充分了解(可以通过RFT测试地图了解)

   (4)开发采用spring管理测试对象地图的脚本比开发有RFT管理的测试对象地图时间要长的多,但是带来的好处也是明显的。

   (5)测试对象执行动作的速度也没有RFT管理的测试对象地图快。

  base-test-object-map.xml 代码

  xml 代码

<!--sp-->xml version="1.0" encoding="gb2312"?>
<!--CTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" </sp-->
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>

<!--注册com.rational.test.ft.script.Property属性编辑器-->
<bean id="customEditorConfigurer" class="org.springframework.beans.factory.config.CustomEditorConfigurer">
<property name="customEditors">
<map>
<entry key="com.rational.test.ft.script.Property">
<bean class="pkg.TestObjectPropertyEditor"/>
entry>
map>
property>
bean>

<!--实例化pkg.BaseTestObjectScript类-->
<bean id="baseTestObjectScript" class="pkg.BaseTestObjectScript"/>

<!--调用baseTestObjectScript中的非静态方法getBrowserTestObject产生一个BrowserTestObject测试对象-->
<bean id="browserTestObject"
factory-bean="baseTestObjectScript"
factory-method="getBrowserTestObject"
singleton="false"/>
<!--调用baseTestObjectScript中的非静态方法getDocumentTestObject产生一个DocumentTestObject测试对象-->
<bean id="documentTestObject"
factory-bean="baseTestObjectScript"
factory-method="getDocumentTestObject"
singleton="false"/>

beans>

  base-test-object-map.xml 可以作为公有的测试对象地图,其中customEditorConfigurer向容器注册了一个属性编辑,pkg.BaseTestObjectScript是一个RFT脚本,此脚本有getBrowserTestObject()和documentTestObject(),可以在这个类中放入基本的测试对象,通过Spring将这些对象封装为bean, 然后有其他的spring配置文件来import,这样就实现了对象的继承。pkg.BaseTestObjectScript的代码如下:

  java 代码

package pkg;

import resources.pkg.BaseTestObjectScriptHelper;

import com.rational.test.ft.*;
import com.rational.test.ft.object.interfaces.*;
import com.rational.test.ft.object.interfaces.siebel.*;
import com.rational.test.ft.script.*;
import com.rational.test.ft.value.*;
import com.rational.test.ft.vp.*;

public class BaseTestObjectScript extends BaseTestObjectScriptHelper
{
public void testMain(Object[] args)
{
}

public BrowserTestObject getBrowserTestObject()
{
return browser_htmlBrowser(document_H(),DEFAULT_FLAGS);
}

public GuiTestObject getDocumentTestObject()
{
return document_H();
}
}

  pkg.TestObjectPropertyEditor代码如下,其中如果用精确匹配就用=作为分隔符,如果是通过正则表达式匹配就通过:作为分隔符,然后在程序内部就会做正则表达式的转换。

  java 代码

package pkg;

import com.rational.test.ft.script.Property;
import java.beans.PropertyEditorSupport;
import java.util.StringTokenizer;
import com.rational.test.ft.value.RegularExpression;

public class TestObjectPropertyEditor extends PropertyEditorSupport
{
public void setAsText(String text)
{
String delimiter = null;
Object propValue = null;

if(text == null || text.length() < 1 || (text.indexOf(EQUAL_MARK) == -1 && text.indexOf(COLON) == -1))
{
throw new IllegalArgumentException("识别属性为空或格式不正确 =表示进行精确匹配 :表示使用正则表达式匹配");
}

if(text.indexOf(EQUAL_MARK) != -1)
{
delimiter = EQUAL_MARK;
}
else if(text.indexOf(COLON) != -1)
{
delimiter = COLON;
}

//解析字符串
StringTokenizer st = new StringTokenizer(text, delimiter);
String name = st.nextToken();
String value = st.nextToken();

propValue = value;

if(text.indexOf(COLON) != -1) //如果分隔符为 : 将propValue设置为正则表达式
{
propValue = new RegularExpression(value, false);
}
setValue(new Property(name, propValue));
}

public String getAsText()
{
Property property = (Property)getValue();
return property.getPropertyName() + "-" + property.getPropertyValue();
}

public final String EQUAL_MARK = "="; //"=" 表示进行精确匹配
public final String COLON = ":"; //":" 表示使用正则表达式匹配
}

  然后介绍一下其他的Spring配置文件通过导入另一个Spring配置文件实现,测试对象的继承。如下,通过import另一个配置文件,这个spring配置文件中的对象就可以使用被导入的spring配置文件中的测试对象,从而可以实现测试对象的继承。

  pkg/logon-map.xml

  xml 代码

<!--sp-->xml version="1.0" encoding="gb2312"?>
<!--CTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" </sp-->
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>

<!--从classpath(类路径)中导入base-test-object-map.xml文件 可以使用base-test-object-map.xml文件中定义的bean-->
<!--导入时候要包含完整的包名-->
<import resource="classpath:pkg/base-test-object-map.xml"/>

<!--实例化pkg.TestObjectHelper类-->
<bean id="loginFormHelper"
class="pkg.TestObjectHelper"
singleton="false">

<!--设置待查找对象的识别属性 格式:propertyName-propertyValue-->
<property name="objectProperties">
<list>
<!--属性名称和属性精确匹配用=-->
<!--属性名称和属性用正则表达式匹配用:-->
<value>.class=Html.FORMvalue>
<value>.name:.*Formvalue>
list>
property>

<!--设置从什么对象开始查找 注入父测试对象-->
<!--browserTestObject 引用的是base-test-object-map.xml文件中已经定义的bean-->
<property name="parentTestObject">
<ref bean="browserTestObject"/>
property>
bean>

<!--调用loginFormHelper中的getSonTestObject 此方法返回TestObject测试对象-->
<bean id="loginForm"
factory-bean="loginFormHelper"
factory-method="getSonTestObject"
singleton="false">
bean>

<!--动态查找text_userName测试对象-->
<bean id="userNameTextHelper"
class="pkg.TestObjectHelper"
singleton="false">
<property name="objectProperties">
<list>
<value>.class=Html.INPUT.textvalue>
<value>.name=userNamevalue>
list>
property>

<property name="parentTestObject">
<ref bean="loginForm"/>
property>
bean>

<!--动态查找text_password测试对象-->
<bean id="userNameText"
factory-bean="userNameTextHelper"
factory-method="getSonTestObject"
singleton="false">
bean>

<bean id="passwordTextHelper"
class="pkg.TestObjectHelper"
singleton="false">
<property name="objectProperties">
<list>
<value>.class=Html.INPUT.passwordvalue>
<value>.name=passWordvalue>
list>
property>

<property name="parentTestObject">
<ref bean="loginForm"/>
property>
bean>

<bean id="passwordText"
factory-bean="passwordTextHelper"
factory-method="getSonTestObject"
singleton="false">
bean>

<!--动态查找ubmit_button测试对象-->
<bean id="submitButtonHelper"
class="pkg.TestObjectHelper"
singleton="false">
<property name="objectProperties">
<list>
<value>.class=Html.INPUT.submitvalue>
<value>.value=进入value>
list>
property>

<property name="parentTestObject">
<ref bean="loginForm"/>
property>
bean>

<bean id="submitButton"
factory-bean="submitButtonHelper"
factory-method="getSonTestObject"
singleton="false">
bean>

<!--点击菜单-->
<bean id="menuHelper"
class="pkg.MenuHelper"
singleton="false">

<!--待点击菜单名称 必须按照先后顺序-->
<property name="menus">
<list>
<value>菜单名称1value>
<value>菜单名称2value>
<value>菜单名称3value>
<value>菜单名称4value>
list>
property>

<!--注入父测试对象 定义从什么对象开始查找菜单并点击-->
<property name="parentTestObject">
<ref bean="documentTestObject"/>
property>
bean>

beans>

  下面是上面的配置文件中用到的pkg.TestObjectHelper类,这个类暴露出parentTestObject 和 objectProperties两个属性用spring来注入,从而确定从什么对象开始查找对象和以什么条件查找对象。通过getSonTestObject() 方法返回找到的测试对象(只允许返回一个对象,如果找到多个就会抛出异常),其中还有个getSonTestObjects()方法是为了返回多个测试对象而准备的。代码如下:

package pkg;

import com.rational.test.ft.AmbiguousRecognitionException;
import com.rational.test.ft.ObjectNotFoundException;
import com.rational.test.ft.object.interfaces.TestObject;
import com.rational.test.ft.script.Property;
import com.rational.test.ft.script.SubitemFactory;

public class TestObjectHelper
{
public Property[] getObjectProperties()
{
return objectProperties;
}

public void setObjectProperties(Property[] objectProperties)
{
this.objectProperties = objectProperties;
}

public TestObject getParentTestObject()
{
return parentTestObject;
}

public void setParentTestObject(TestObject parentTestObject)
{
this.parentTestObject = parentTestObject;
}

public TestObject getSonTestObject()
{
return findSonTestObject();
}

public void setSonTestObject(TestObject sonTestObject)
{
this.sonTestObject = sonTestObject;
}

  查阅关于Spring的全部文档

(转载文章请保留出处:北天JAVA技术网(www.java114.com))
 
更多精彩文章:
彻底明白 Java 语言中的IO系统
为Java程序中添加播放MIDI音乐功能
Spring破冰之旅 始于足下
Spring中事件处理的小技巧
JavaBean中使用JDBC方式进行事务处理
争鸣:Java的Web框架 让我如何去爱你
 
最近评论:
        
冰封的往事!
wow power leveling,wow gold,wow power leveling,wow gold max(1652)
        
冰封的往事!
wow power leveling,wow gold,WoW Gold,wow gold max(4202)
        
飞舞的传奇!
传世私服,传世私服.传奇世界私服传奇世界私服,传世私服传世私服, 传奇世界私服传奇世界私服.传奇私服传奇私服. max(9020)
        
飞舞的传奇!
传世私服,传世私服.传奇世界私服传奇世界私服,传世私服传世私服, 传奇世界私服传奇世界私服.传奇私服传奇私服. max(7697)
        
飞舞的传奇!
传世私服,传世私服.传奇世界私服传奇世界私服,传世私服传世私服, 传奇世界私服传奇世界私服.传奇私服传奇私服. max(5046)
        
飞舞的传奇!
传世私服,传世私服.传奇世界私服传奇世界私服,传世私服传世私服, 传奇世界私服传奇世界私服.传奇私服传奇私服. max(4133)
        
标 题:   
内 容:   
 
                                  
 
免责声明:该文章由网友发表,如果对您造成侵权,请联系站长

首页 - 承接项目 - 网站地图 - 联系我们 -
版权所有北天JAVA技术工作室 ICP证号:粤ICP备06079815号