Rational Functional Tester (RFT) 是一款集成在Eclipse上的自动化测试工具。而自动化测试最麻烦的维护部分,一大部分也是指的是对象库文件的管理维护。

之前的项目里,经常遇到对象库文件有冲突,虽然我们有用Rational Team Concert (RTC) 去做compair & merge 的工作,但是还是不是太理想,有时候还是会遇到一些文件的冲突(主要是对象文件,“*.rftdef”文件,以及与之相关的helper文件)。下图就是一个典型的rftdef文件,很容易看出其本质就是个xml文件

而冲突的内容主要就是<TestObject>元素的冲突。其实就是两个XML文件的合并。

我用python写了个RftDef类去将不同的<TestObject>元素加在最后

# RftDef
# $Id: RftDef.py 2014-11-17 SunYu$
#
# light-wight Rational Functional Tester Object definition files
# '*.rftdef' merge support for Python 3.3 and later.
#
# Sample of RFT test object map
# RftDef is target to merge <TestObject/> in 2 different files
#
# <?xml version="1.0" encoding="UTF-8"?>
# <ScriptDefinition L=".ScriptDefinition">
# <ScriptName/>
# <Language/>
# <Map/>
# <Datapool/>
# <DatapoolIterator/>
# <HelperSuper/>
# <ScriptNameMap L=".ScriptDefinitionNameMap">
# <TestObject L=".ScriptDefNameMapElement">
# <Name>kw_AVProposalDetails_btn_cancelbutton</Name>
# <ID>Nn.SFdtlx8A898:EjdFp:NhRhOwR:8WU</ID>
# <Role>Button</Role>
# <Deleted>false</Deleted>
# </TestObject>
# .........
# </ScriptNameMap>
# <Properties L=".PropSet"/>
# <ScriptEncoding>Cp1252</ScriptEncoding>
# <KeywordName/>
# <VisualScriptName/>
# <DatapoolSet L=".DatapoolSet"/>
# </ScriptDefinition> from xml.etree import ElementTree as ET
import os,sys class RftDef:
def __init__(self, path=None, f1=None, f2=None):
if not path:
#change python workspace to current folder
self._path = sys.path[0]
else:
self._path = path os.chdir(self._path) if not f1:
self._f1 = self.__getFileName()
else:
self._f1 = f1
if not f2:
self._f2 = self.__getFileName("second")
else:
self._f2 = f2 self.__validFileName()
#ElementTree f1,f2
self._et1 = ET.parse(self._f1)
self._et2 = ET.parse(self._f2)
#list to merge
self._lstEt1 = list()
self._lstEt2 = list() def __str__(self):
return ("Path %s\n"
"f1 %s\n"
"f2 %s\n"
"et1 %s\n"
"et2 %s\n"
"lstEt1 %s\n"
"lstEt2 %s"
% (self._path,
self._f1,
self._f2,
self._et1,
self._et2,
self._lstEt1,
self._lstEt2)
) def __getFileName(self,s="first"):
return input("Please input %s file name\n" % s) def __validFileName(self):
if not self._f1.endswith(".rftdef"):
self._f1 = self._f1 + ".rftdef"
if not self._f2.endswith(".rftdef"):
self._f2 = self._f2 + ".rftdef" self._f1 = self._path + "/" + self._f1
self._f2 = self._path + "/" + self._f2 if not os.path.exists(self._f1):
raise ValueError("%s is not a valid file path!"
" Please check." % self._f1)
if not os.path.exists(self._f2):
raise ValueError("%s is not a valid file path!"
" Please check." % self._f2) def __mergeList(self):
""" see sample structure of rftdef above """
lstEt1 = list()
lstEt2 = list()
lstDiff = list()
for obj in self._lstEt1:
for attr in obj:
if(attr.tag=="Name"):
lstEt1.append(attr.text)
for obj in self._lstEt2:
for attr in obj:
if(attr.tag=="Name"):
lstEt2.append(attr.text) for objName in lstEt1:
if objName not in lstEt2:
lstDiff.append(objName)
for objName in lstEt2:
if objName not in lstEt1:
lstDiff.append(objName) if len(lstDiff) <= 0:
return "These 2 files are the same." lstTemp = self._lstEt1
for objName in lstDiff:
for obj in self._lstEt2:
for attr in obj:
if(attr.text == objName):
lstTemp.append(obj)
return lstTemp def parse(self,xpath = "./ScriptNameMap/TestObject"): """ xpath default is './ScriptNameMap/TestObject'
'.' stands for root
""" self._lstEt1 = self._et1.findall(xpath)
self._lstEt2 = self._et2.findall(xpath) if self._lstEt1 == None or self._lstEt2 == None:
raise ValueError("%s is not a valid xpath." % xpath) def write(self, out="out.rftdef"):
lstTemp = self.__mergeList()
#clear <ScriptNameMap>
tar = self._et1.find("./ScriptNameMap")
tar.clear()
for i in lstTemp:
tar.append(i)
self._et1.write(out,"utf-8",True) if not os.path.exists(self._path + "/" + out):
return "Unknow Error in Merge File!"
else:
return "Merge files sucessful!" rft = RftDef("","test1","test2")
rft.parse()
rft.write()

上面的代码会比较两个rftdef文件 test1 和 test2,最后生成的是out.rftdef文件

附test1.rftdef文件,test2则是自己随便改了些<TestObject> Name里面的内容

<?xml version="1.0" encoding="UTF-8"?>
<ScriptDefinition L=".ScriptDefinition">
<ScriptName>Business.CP_UILib.PtyVal</ScriptName>
<Language>java</Language>
<Map>ObjectMap/ObjectsRepository_CP.rftmap</Map>
<Datapool/>
<DatapoolIterator>com.rational.test.ft.datapool.SequentialIterator</DatapoolIterator>
<HelperSuper>Business.Helpers.CP.BusinessHelper</HelperSuper>
<ScriptNameMap L=".ScriptDefinitionNameMap">
<TestObject L=".ScriptDefNameMapElement">
<Name>kw_ViewAndCreateTrigger_lbl_html_TrigReasonVal</Name>
<ID>OP.SFdtlx8A898:tfcq3:Ni6hV0h:8WT</ID>
<Role>Html</Role>
<Deleted>false</Deleted>
</TestObject>
<TestObject L=".ScriptDefNameMapElement">
<Name>kw_ViewAndCreateTrigger_txt_dtpPropDateDateBox</Name>
<ID>ON.SFdtlx8A898:tfcq3:Ni6hV0h:8WT</ID>
<Role>Text</Role>
<Deleted>false</Deleted>
</TestObject>
</ScriptNameMap>
<Properties L=".PropSet"/>
<ScriptEncoding>Cp1252</ScriptEncoding>
<KeywordName/>
<VisualScriptName/>
<DatapoolSet L=".DatapoolSet"/>
</ScriptDefinition>

Rational Functional Tester 对象文件(rftdef)合并的更多相关文章

  1. 关于Rational Functional Tester (RFT)的简单介绍

    前段时间给客户做了个RFT的简单培训,以下.因为涉及到公司的框架,所以中间省去了很多框架里的细节,只留了一个框架的总体结构的概览. RFT IBM Rational Functional Tester ...

  2. Wrapping calls to the Rational Functional Tester API——调用Rational Functional Tester封装的API

    转自:http://www.ibm.com/developerworks/lotus/library/rft-api/index.html The Rational GUI automation to ...

  3. 安装builderRobot到Rational Functional Tester和Performance Tester

    最近研究安装builder,稍微总结一下,以后继续补充: 1. Robot采用专业的测试脚本语言, 从而导致需要学习专门的API以及专门的语法外, 用进程化的Visual Basic作为脚本语言, 导 ...

  4. JAVA之旅(三十)——打印流PrintWriter,合并流,切割文件并且合并,对象的序列化Serializable,管道流,RandomAccessFile,IO其他类,字符编码

    JAVA之旅(三十)--打印流PrintWriter,合并流,切割文件并且合并,对象的序列化Serializable,管道流,RandomAccessFile,IO其他类,字符编码 三十篇了,又是一个 ...

  5. JS&CSS文件请求合并及压缩处理研究(四)

    本篇将会尝试对之前的代码进行相关的单元测试,验证路径合并规则的覆盖率及正确性. 熟悉 ASP.NET MVC 开发的朋友应该知道,微软在MVC框架下集成了一款名为 Microsoft.VisualSt ...

  6. 服务器端json数据文件分割合并解决方案

    问题引入 Json 是什么就不多说了,本文把Json理解成一种协议. 印象之中,Json貌似是前端的专属,其实不然,服务器端组织数据,依然可以用Json协议. 比如说,某公司有一套测评题目(基于Jso ...

  7. JS&CSS文件请求合并及压缩处理研究(三)

    上篇我们进行了一些代码方面的准备工作.接下来的逻辑是:在View页面解析时,通过 Html.AppendResFile 方法添加的资源文件,我们需要按照分组.优先级,文件名等条件,对其路径进行合并.具 ...

  8. node 读取多个文件、合并多个文件、读写多个文件

    一.读取文件 1.找文件中匹配的内容 let fs = require('fs') let content = fs.readFileSync('/Users/**/desktop/Test.txt' ...

  9. ASP.NET MVC 4 Optimization的JS/CSS文件动态合并及压缩

    JS/CSS文件的打包合并(Bundling)及压缩(Minification)是指将多个JS或CSS文件打包合并成一个文件,并在网站发布之后进行压缩,从而减少HTTP请求次数,提高网络加载速度和页面 ...

随机推荐

  1. HTML网页调用本地QQ

    打开聊天窗口代码: tencent://message/?uin=QQ号码&Site=有事Q我&Menu=yes 使用方法: <a href="tencent://me ...

  2. item30,最小的k个数

    剑指offer给出两类方法: 1,借助快排的思想,需要修改输入数组的元素,时间复杂度O(n) 2,借助STL中set或者multiset,因为它们的底层数据结构是红黑树实现的,插入数据时间复杂度为O( ...

  3. hadoop作业调优参数整理及原理(转)

    1 Map side tuning参数 1.1 MapTask运行内部原理 当map task开始运算,并产生中间数据时,其产生的中间结果并非直接就简单的写入磁盘.这中间的过程比较复杂,并且利用到了内 ...

  4. RAC_Oracle集群服务安装前期准备Prepare(案例)

    2014-07-08 Created By BaoXinjian

  5. M2M

    1, M2M (数据算法模型) M2M是将数据从一台终端传送到另一台终端,也就是机器与机器(Machine to Machine)的对话.   M2M简介 但从广义上M2M可代表机器对机器(Machi ...

  6. CentOS配置网卡,重启网络显示:Device does not seem to be present(转载)

    From:http://www.cnblogs.com/fbwfbi/archive/2013/04/29/3050907.html 一.故障现象: [root@c1node01 ~]# servic ...

  7. 记录更新rbenv 和 ruby-build安装2.3的ruby注意细节

    安装就不说了,官网有,但是今天发布了ruby2.3,所以更新一下 进入.rbenv目录,执行git pull 更新,但是更新了rbenv,执行rbenv install -l 并没有最新的2.3.0 ...

  8. C++学习44 格式化输出,C++输出格式控制

    在输出数据时,为简便起见,往往不指定输出的格式,由系统根据数据的类型采取默认的格式,但有时希望数据按指定的格式输出,如要求以十六进制或八进制形式输出一个 整数,对输出的小数只保留两位小数等.有两种方法 ...

  9. 《一课经济学》书摘笔记IV

    有出口,才有钱进口:没有进口,就没有机会出口,因为外国人没有美元可以用来买美国的产品.要想扩大出口,就必须有更多的进口,否则收不到货款.要想压缩进口,出口也会随之被压缩.所以,当我们决定减少进口的时候 ...

  10. ROWNUM-Oracle中的分页代码

    SELECT * FROM (SELECT ENAME,SAL,ROWNUM RN FROM EMP WHERE ROWNUM <= @CURRENTPAGE*@PAGESIZE) SUB );