• Rational Functional Tester 对象文件(rftdef)合并


    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
    "
                    "f1 %s
    "
                    "f2 %s
    "
                    "et1 %s
    "
                    "et2 %s
    "
                    "lstEt1 %s
    "
                    "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
    " % 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>
  • 相关阅读:
    定时器
    按键中断部分的理解
    初中数学
    WING IDE 快捷键
    机器学习各种网址
    SQL With As 用法Sql 四大排名函数(ROW_NUMBER、RANK、DENSE_RANK、NTILE)简介
    Python编码格式导致的csv读取错误
    Oracle中的rownum 和rowid的用法和区别
    oracle配置
    matplotlib命令与格式:标题(title),标注(annotate),文字说明(text)
  • 原文地址:https://www.cnblogs.com/ryansunyu/p/4106093.html
Copyright © 2020-2023  润新知