自动化脚本批量运行机制

在自动化测试过程中,我们编写了很多的测试脚本,每一次都要运行n多个脚本,由于每次运行的目的、脚本的数量、涉及的业务或测试范围不一样,因此我们要配置我们要运行的测试脚本。此外,运行的过程中我们要收集脚本运行的状况,是否运行成功?如果运行失败是否要收集失败脚本的名称、捕捉失败脚本的异常信息等。这一串的流程我们应该怎么实现呢,下面我就给大家介绍一种我自己实现的配置流程
1.创建脚本运行配置文件【project.xml】来配置运行脚本
<?xml version="1.0" encoding="gb2312"?>
<pathsConfig>
                  <!-- 流程定义配置文件 name为项目名称,version为项目版本号 -->
         <project name="koala" version="v1.3">
                                <!-- 流程套件 -->
                 <suite name="测试">
                                      <!-- 流程环节 -->
                     <step name="我的测试">
                                                      <!-- 测试用例脚本配置 -->
                             <case name="测试用例1">com.autoTest.project.base.test.cases.H_Test1</case>
                             <case name="测试用例2">com.autoTest.project.base.test.cases.M_Test2</case>
                         </step>                         
                 </suite>

         </project>
</pathsConfig>

2.通过一个读取xml的java类来获取配置文件中需要运行的脚本
创建读取xml的基础类
public class ReadXml {
     
        private  SAXReader reader;  //解析器
        private  Document dom;      //document对象
        public ReadXml(){
                
        }
        
        /**
         * 实例化ReadXml类并加载xml文件
         * @param xmlPath
         */
        public ReadXml(String xmlPath){
                
                this.initDomFile(xmlPath);
        }
        
        /**
         * 加载xml文件
         * @param xmlPath
         */
        public void initDomFile(String xmlPath){
                
           //通过文件路径创建File对象
           File xmlFile=new File(xmlPath);
           //实例化xml解析器
           reader=new SAXReader();
           try{
                   //通过加载文件实例化document对象
                   dom=reader.read(xmlFile);
           }catch(Exception e){
                   System.out.println("加载xml文件失败,请检查文件路径是否正确");
                   e.printStackTrace();
           }
        }
        
        /**
         * 通过节点路径读取xml节点
         * @param nodePath   节点路径 格式例【//widget[@name='"+name+"']/property】
         * @return List<Node>
         */
        @SuppressWarnings("unchecked")
        public List<Node> getNodeList(String nodePath){
                
                //用list封装给定条件下的所有节点
                List<Node> nodeList=new ArrayList<Node>();
                //获取根节点
                //Element rootElement=dom.getRootElement(); 
                //获取某节点下的某属性
                try{
                        //调用document对象的selectNodes获取符合条件的节点赋给nodeList
                        nodeList =dom.selectNodes(nodePath);
                }catch(Exception e){
                        e.printStackTrace();
                        System.out.println("读取元素出错请检查nodePath参数");
                }                
                return nodeList;
        }
        
        /**
         * 通过节点路径获取ElementList
         * @param nodePath  节点路径 格式例【//widget[@name='"+name+"']/property/key】
         * @return List<Element>
         */
        @SuppressWarnings("unchecked")
        public List<Element> getElementList(String nodePath){
                
                List<Element> elementList=new ArrayList<Element>();
                try{
                        elementList=dom.selectNodes(nodePath);
                }catch(Exception e){
                        e.printStackTrace();
                        System.out.println("读取元素出错请检查nodePath参数");
                }
                
                return elementList;
        }
        
        /**
         * 通过节点路径获取节点文本值
         * @param nodePath 节点路径 格式例【//widget[@name='"+name+"']/property】
         * @return List<String>
         */
        public List<String> getNodeTexts(String nodePath){
                
                List<String> nodeText=new ArrayList<String>();
                List<Node> nodeList=new ArrayList<Node>();
                nodeList=this.getNodeList(nodePath);
                if(nodeList.size()>0){
                        for(Node node:nodeList){
                                nodeText.add(node.getText());
                        }
                }
                return nodeText;                
        }
        
        /**
         * 通过节点路径获取节点文本值
         * @param nodePath 节点路径 格式例【//widget[@name='"+name+"']/property】
         * @return String
         */
    public String getNodeText(String nodePath){
                
                String nodeText="";
                List<String> strList=this.getNodeTexts(nodePath);
                if(strList.size()>0){
                        nodeText=strList.get(0);
                }
                return nodeText;                
        }
    
        /**
         * 通过节点路径获取及节点属性名称获取属性值
         * @param nodePath   节点路径 格式例【//widget[@name='"+name+"']/property】
         * @param AttributeName 属性名称 例【name】
         * @return List<String>
         */
    public List<String> getNodeAttributes(String nodePath,String AttributeName){
                
            List<String> attList=new ArrayList<String>();
                List<Element> elementList=this.getElementList(nodePath);
                if(elementList.size()>0){
                        for(Element elem:elementList){
                                String AttributeValue =elem.attributeValue(AttributeName);
                                attList.add(AttributeValue);
                        }                        
                }
                return attList;
        }
    
    /**
         * 通过读取节点路径及节点属性名称获取属性值
         * @param nodePath   节点路径 格式例【//widget[@name='"+name+"']/property】
         * @param AttributeName  属性名称 例【name】
         * @return String
         */
        public String getNodeAttribute(String nodePath,String AttributeName){
                
                String attValue="";
                List<String> strList=this.getNodeAttributes(nodePath, AttributeName);
                if(strList.size()>0){
                        attValue=strList.get(0);
                }
                return attValue;
        }
        
        
        /**
         * 通过字节点的文本值获取父节点的某一属性的属性值
         * @param nodeText 节点文本值
         * @param nodePath 节点路径
         * @param attributeName 节点属性名
         * @return
         */
        public String getParentName(String nodeText,String nodePath,String attributeName){
                String name="";
                List<Node> keyList=this.getNodeList(nodePath);
                for(Node em:keyList){
                        if(em.getText().equals(nodeText)){
                                name=em.getParent().attributeValue(attributeName);
                                break;
                        }
                }
                return name;
        }

创建读取脚本运行配置文件的读取脚本的java类
public class ReadProXml {
        
        ReadXml  read;
        public ReadProXml(String xmlPath){
                read=new ReadXml(xmlPath);
        }
        
        /**
         * 读取脚本配置xml文件中的单个脚本路径
         * @param caseName case节点下的name属性
         * @return List<String>
         */
        public List<String> getCasePathByXml(String caseName){
                
                List<String> caseScrPath=new ArrayList<String>();
                String casePath="//case[@name='"+caseName+"']";
                caseScrPath=read.getNodeTexts(casePath);
                return caseScrPath;
        }
        
        /**
         * 读取脚本配置文件中step节点下的所有脚本路径
         * @param stepName step节点的name属性
         * @return List<String>
         */
        public List<String> getCasePathByStep(String stepName){
                
                List<String> caseScrPathList=new ArrayList<String>();
                String stepPath="//step[@name='"+stepName+"']//case";
                caseScrPathList=read.getNodeTexts(stepPath);
                return caseScrPathList;
        }
        
        /**
         * 读取脚本配置xml文件中suit节点下的所有脚本路径
         * @param suitName  suit节点下的name属性
         * @return List<String>
         */
        public List<String> getcasePathBySuite(String suiteName){
                
                List<String> caseScrPathList=new ArrayList<String>();
                String suitPath="//suite[@name='"+suiteName+"']//case";
                caseScrPathList=read.getNodeTexts(suitPath);
                return caseScrPathList;
        }
        
        /**
         * 读取脚本配置xml文件中的所有case节点的文本
         * @return
         */
        public List<String> getAllCasePathbyXml(){
                
                List<String> caseScrPathList=new ArrayList<String>();
                String path="//case";
                caseScrPathList=read.getNodeTexts(path);
                return caseScrPathList;
        }

3.编写脚本运行类
public class RunScript {
                 public  RunScript(){
                
         }
         
         /**
          *执行脚本,并记录脚本执行的开始时间、结束时间、执行结果、脚本名称
          * @param scrPath  脚本路径
          * @return RunScriptResult
          */
         public  void runScript(String scrPath){
                  RunScriptResult scrRes=new RunScriptResult();
                  boolean runState=true;
                  try{
                          //调用脚本
                          callScript(scrPath);        
                          //记录脚本运行状态
                          scrRes.setRunState(runState);
                          //记录运行的脚本名称
                          scrRes.setScriptName(scrPath);
                           //收集脚本运行的信息
                          RunScriptCollector.getRunScriptResult(scrRes);
                  }catch(Exception e){
                          runState=false;
                          //收集运行的脚本名称
                          scrRes.setScriptName(scrPath);                          
                          scrRes.setRunState(runState);
                          //记录脚本运行失败信息
                          scrRes.setFailInfo(e.getMessage());
                          //收集脚本运行的信息
                          RunScriptCollector.getRunScriptResult(scrRes);
                  }        
                          
          }
4.脚本运行收集类

public class RunScriptCollector {
     
public static List<RunScriptResult>  scrList=new ArrayList<RunScriptResult>();
        
        public static void getRunScriptResult(RunScriptResult scr){
                scrList.add(scr);
        }
}
5.脚本运行分析类
/**
            * 获取脚本执行信息汇总内容,生成word文档用
            * @param runList RunScriptResult脚本运行结果实体类【脚本名称、运行结果、失败信息】
            * @return
            */
           public ArrayList<String[]> getScrRunGatherInfo(List<RunScriptResult> runScrList){
                    
                   ArrayList<String[]> scrRunGatherInfo=new ArrayList<String[]>();
                   int Main_Pass=0;  //Main级别的成功的脚本数量
                   int Main_Fail=0;  //Main级别的失败的脚本数量
                   int Main_Total=0; //Main级别的脚本总数量
                   int H_Pass=0;    //H级别的成功的脚本数量
                   int H_Fail=0;    //H级别的失败的脚本数量
                   int H_Total=0;   //H级别的脚本总数量
                   int M_Pass=0;    //M级别的成功的脚本数量
                   int M_Fail=0;    //M级别的失败的脚本数量
                   int M_Total=0;   //M级别的脚本总数量
                   int L_Pass=0;   //L级别的成功的脚本数量
                   int L_Fail=0;   //L级别的失败的脚本数量
                   int L_Total=0;  //L级别的脚本总数量
                   int sum_Pass=0; //成功脚本总数量
                   int sum_Fail=0; //失败脚本总数量
                   int sum_Total=runScrList.size(); //脚本总数量                   
                   for(RunScriptResult res:runScrList){
                           //获取脚本名称【x.x.x.ClassName】
                           String scrName=res.getScriptName();
                           //将脚本名称分解为脚本名称数组,并获取脚本类名
                           String[] arrName=scrName.split("\\.");
                           String className=arrName[arrName.length-1];
                           //从脚本类名中获取脚本执行的级别
                           String lever=className.split("_")[0];
                           if(lever.equals("Main")){//如果脚本级别为Main
                                   if(res.getRunState()){ //判断Main级别的脚本运行成功即true
                                           Main_Pass++; //Main级别脚本成功数加1
                                   }else{ //如果Main级别的脚本执行失败即false
                                           Main_Fail++; //Main级别脚本失败数加1
                                   }
                           }else if(lever.equals("H")){ //如果脚本级别为H
                                   if(res.getRunState()){ //判断H级别的脚本执行成功即true
                                           H_Pass++; //H级别脚本成功数加1
                                   }else{ //如果H级别的脚本执行失败即false
                                           H_Fail++; //H级别脚本的失败数加1
                                   }
                           }else if(lever.equals("M")){ //如果脚本级别为M
                                   if(res.getRunState()){ //判断M级别的脚本运行成功
                                           M_Pass++; //M级别脚本成功数加1
                                   }else{ //如果M级别的脚本运行失败
                                           M_Fail++; //M级别脚本失败数加1
                                   }
                           }else if(lever.equals("L")){ //如果脚本运行的级别为L
                                   if(res.getRunState()){ //判断L级别的脚本执行成功即true 
                                           L_Pass++; //L级别脚本成功数加1
                                   }else{ //如果L级别的脚本执行失败
                                           L_Fail++; //L级别脚本失败数加1
                                   }
                           }else{
                                   System.out.println("脚本格式错误!"+scrName);
                           }                           
                   }
                   Main_Total=Main_Pass+Main_Fail; //计算M级别的脚本执行的总数
                   H_Total=H_Pass+H_Fail; //计算H级别的脚本执行的总数
                   M_Total=M_Pass+M_Fail; //计算M级别的脚本执行的总数
                   L_Total=L_Pass+L_Fail; //计算L级别的脚本执行的总数
                   sum_Pass=Main_Pass+H_Pass+M_Pass+L_Pass; //计算脚本执行成功的脚本数
                   sum_Fail=Main_Fail+H_Fail+M_Fail+L_Fail; //计算脚本执行失败的脚本数
                   //通过获取的各种脚本执行统计,生成脚本执行数组
                   //声明main数组封装Main级别的脚本执行的成功数、失败数和总数
                   String[] main={"Main",String.valueOf(Main_Pass),String.valueOf(Main_Fail),String.valueOf(Main_Total)};
                   //声明h数组封装H级别的脚本执行的成功数、失败数和总数
                   String[] h={"H",String.valueOf(H_Pass),String.valueOf(H_Fail),String.valueOf(H_Total)};
                   //声明m数组封装M级别的脚本执行的成功数、失败数和总数
                   String[] m={"M",String.valueOf(M_Pass),String.valueOf(M_Fail),String.valueOf(M_Total)};
                   //声明l数组封装L级别的脚本执行的成功数、失败数和总数
                   String[] l={"L",String.valueOf(L_Pass),String.valueOf(L_Fail),String.valueOf(L_Total)};
                   //声明sun数组封装脚本执行的成功总数、失败总数和总数
                   String[] sum={"Total",String.valueOf(sum_Pass),String.valueOf(sum_Fail),String.valueOf(sum_Total)};
                   //将各类数组信息封装到scrRunGatherInfo实体类中
                   scrRunGatherInfo.add(main);
                   scrRunGatherInfo.add(h);
                   scrRunGatherInfo.add(m);
                   scrRunGatherInfo.add(l);
                   scrRunGatherInfo.add(sum);
                   
                   return scrRunGatherInfo;

/**
            * 获取失败脚本详细信息 
            * @param runScrList RunScriptResult脚本运行结果实体类【脚本名称、运行结果、失败信息】
            * @return
            */
           public ArrayList<String[]> getFailScrDetailInfo(List<RunScriptResult> runScrList){
                   ArrayList<String[]> failScrDetailInfo=new ArrayList<String[]>();
                   for(RunScriptResult runScriptResult:runScrList){//循环遍历每一个脚本执行信息RunScriptResult
                           //获取脚本名称ScrNname【x.x.x.scrName】
                           String scrName=runScriptResult.getScriptName();
                           if(!runScriptResult.getRunState()){//判断脚本执行结果为成功即true
                                   //声明数组arr封装脚本名称和失败信息【{"脚本名称","失败信息"}】
                                   String[] arr=new String[2]; 
                                   arr[0]=scrName;
                                   arr[1]=runScriptResult.getFailInfo();
                                   //添加到脚本失败信息list中
                                   failScrDetailInfo.add(arr);
                           }
                   }
                   return failScrDetailInfo;
           }
5.编写脚本运行驱动类来读取project.xml中的脚本,通过脚本运行类一个一个的执行脚本并收集脚本执行情况信息
public class Project{
        public void testMain(Object[] args) 
        {
                // TODO 在此插入代码
                // TODO 在此插入代码
                String caseXmlPath="com\\autoTest\\project\\base\\project.xml";
                ReadProXml read=new ReadProXml(caseXmlPath);
                List<String> caseScrList=new ArrayList<String>();
                //执行单个脚本
                //String caseName="Main_Koala_许可受理_设立许可(来源于已核名未设立)";
                //caseScrList=read.getCasePathByXml(caseName);
                
                //执行step节点下的所有脚本
                String stepName="我的测试";
                caseScrList=read.getCasePathByStep(stepName);
                //执行suite节点下的所有脚本
                //String suiteName="";
                //caseScrList=read.getcasePathBySuite(suiteName);
                
                
                //执行所有的用例脚本
                //caseScrList=read.getAllCasePathbyXml();
                RunScript run = new RunScript();
                
                CustomDateAndTime dt=new CustomDateAndTime();
                //脚本运行获取开始时间
                Date startTime=new Date();
                for(String caseScrName:caseScrList){
                        try{
                                run.runScript(caseScrName);
                        }catch(Exception e){
                                System.out.println(caseScrName+"异常信息:"+e.getMessage());
                        }
                        
                }
                //脚本运行结束获取运行时间
                Date endTime=new Date();
                //封装脚本运行的开始时间,结束时间、及运行时长
                SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                String[] runTime=new String[3];
                runTime[0]=df.format(startTime);
                runTime[1]=df.format(endTime);
                runTime[2]=dt.getIntervalTime(startTime, endTime);
                
                //配置是否生成word测试报告                
                CreateReport word=new CreateReport("D:\\Report.doc","D:\\ReportModel.doc");
                word.createReport(RunScriptCollector.scrList,VerifyCollector.verifyList,runTime);
                
                //配置生成Text测试报告
                //CreateText txt=new CreateText("com\\autoTest\\project\\base\\test\\res\\report.txt");
                //txt.writeToText(RunScriptCollector.scrList,VerifyCollector.verifyList);
                //配置运行后是否生成并打开测试结果html网页
                //CreateHtml html=new CreateHtml("com\\autoTest\\project\\base\\test\\res\\report.html");
                //html.createHtml(RunScriptCollector.scrList,VerifyCollector.verifyList);
                //配置是否发送邮件  
                //SendMailByOutLook send=new SendMailByOutLook();
                //填写用户名、密码、邮件标题、发送地址(多个发件人以;隔开、上传的附件地址【多个附件以;隔开】)
                //send.setPluginMail("qiaojunpeng", "19860406", "测试邮件","qiaojunpeng@topnet.local","qiaojunpeng@topnet.local","com\\autoTest\\project\\base\\test\\res\\report.txt;com\\autoTest\\project\\base\\test\\res\\report.html");
        }
}
上述只是一种实现逻辑,仅供参考。

特别注明:大家做自动化测试不要墨守成规,太多的工具都有优缺点,如果工具的一些功能我们得到的东西太少,那么我们就应该尝试着自己写代码是去实现我们想要的东西。




http://www.51autotest.com/forum.php?mod=viewthread&tid=2339&reltid=1827&pre_thread_id=1854&pre_pos=8&ext=CB


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值