Web自动化测试构建学习小结(一)

Web自动化测试的框架:Selenium+JAVA+TestNG

Selenium

1.使用Selenium IDE(firefox的组件,可以在firefox上加载安装)录制初步的脚本,可转换成自己需要的编码。(选择了JAVA):要熟悉Selenium定位页面元素的相关知识

2.使用Selenium 2优化脚本:1>eclipse下加载Selenium 2的jar包

                                      2>实现测试数据、页面元素、测试逻辑三部分的分离(测试数据用excel保存、页面元素用xml保存并分别封装处理类)

  测试数据处理类:

  public class DataHelper {
    
    //获取xls表格的里面的表
    public static Sheet DataOpen(String urlSource) throws BiffException, IOException{
        File file=new File(urlSource);
        Workbook workbook=Workbook.getWorkbook(file);
        Sheet sheet=workbook.getSheet(0);
        return sheet;
    }
    //按行、列获取表格里的数据
    public static String getString(int index1,int index2,Sheet sheet) throws BiffException, IOException{
        Cell cell=sheet.getCell(index1, index2);
        return cell.getContents();
    }   
}

页面元素处理类

public class PostElement {
    static int row=1;
    static int Column=1;
    static boolean acceptNextAlert = true;
    static Log log=LogFactory.getLog(PostElement.class);
    
    
    //获取XML文件中需要遍历的节点
    public static NodeList doc(String str) throws ParserConfigurationException, SAXException, IOException{
       DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();
       DocumentBuilder db=factory.newDocumentBuilder();
       InputStream is = new FileInputStream(new File(str));
       Document doc=db.parse(is);
       Element root=doc.getDocumentElement();//取得根节点
       NodeList nodes=root.getElementsByTagName("node");
       return nodes;
    }
    //获取Element的操作并执行
    public static void operator(WebDriver driver,WebElement element,Node node,Sheet sheet) throws BiffException, IOException{
        if(node.getAttributes().getNamedItem("type").getNodeValue().equals("text"))
        {    
            element.clear();
            element.sendKeys(DataHelper.getString(Column, row,sheet));
            log.info("第"+row+"行"+"第"+Column+"列"+"数据:"+DataHelper.getString(Column, row,sheet));
            //System.out.println("第"+row+"行"+"第"+Column+"列"+"数据:"+DataHelper.getString(Column, row,sheet));
            Column++;
            if(Column==sheet.getColumns()){
                Column=1;
                row++;
            }
            if(row==sheet.getRows()){
                row=1;
            }
            //System.out.println("最后的行"+row);
            //System.out.println("最后的列"+Column);
            
        }
        if(node.getAttributes().getNamedItem("type").getNodeValue().equals("button")||node.getAttributes().getNamedItem("type").getNodeValue().equals("submit")){
            try{
                    Thread.sleep(1000);//解决click不响应的问题
                }catch(InterruptedException e){
                    e.printStackTrace();
                }
                
            element.click();
            try{
                Thread.sleep(3000);//解决click不响应的问题
            }catch(InterruptedException e){
                e.printStackTrace();
            }
        if(isAlertPresent(driver)){
            closeAlertAndGetItsText(driver);
        }
        }
    }
    //自动捕获弹出框
    private static boolean isAlertPresent(WebDriver driver) {
        try {
          driver.switchTo().alert();
          return true;
        } catch (NoAlertPresentException e) {
          return false;
        }
      }

      private static void closeAlertAndGetItsText(WebDriver driver) {
        try {
          Alert alert = driver.switchTo().alert();
          String alertText = alert.getText();
          if (acceptNextAlert) {
            alert.accept();
          } else {
            alert.dismiss();
          }
        } finally {
          acceptNextAlert = true;
        }
      }
      //判断页面元素是否可操作
    //按ID遍历节点
    public static WebElement getID(WebDriver driver,Node node) throws ParserConfigurationException, SAXException, IOException, BiffException{
        WebElement element=null;
    if(node.getNodeType()==Node.ELEMENT_NODE){
                
                if(node.getAttributes().getNamedItem("id")!=null){                
                    element=driver.findElement(By.id(node.getAttributes().getNamedItem("id").getNodeValue()));
                }
        }
         return element;        
    }
    //按name遍历节点
    public static WebElement getName(WebDriver driver,Node node) throws ParserConfigurationException, SAXException, IOException, BiffException{
        WebElement element=null;
            if(node.getNodeType()==Node.ELEMENT_NODE){
                
                if(node.getAttributes().getNamedItem("name")!=null){
                    element=driver.findElement(By.name(node.getAttributes().getNamedItem("name").getNodeValue()));
                }
            }
         return element;        
        
    }
    //按class遍历节点
    public static WebElement getClass(WebDriver driver,Node node) throws ParserConfigurationException, SAXException, IOException, BiffException{
        WebElement element=null;
            if(node.getNodeType()==Node.ELEMENT_NODE){
                
                if(node.getAttributes().getNamedItem("class")!=null){
                    element=driver.findElement(By.className(node.getAttributes().getNamedItem("class").getNodeValue()));
                }
                
            }
         return element;        
    }
    //按css遍历节点
    public static WebElement getcssSelector(WebDriver driver,Node node) throws ParserConfigurationException, SAXException, IOException, BiffException{
        WebElement element=null;
            if(node.getNodeType()==Node.ELEMENT_NODE){
                
                if(node.getAttributes().getNamedItem("css")!=null){
                    element=driver.findElement(By.cssSelector(node.getAttributes().getNamedItem("css").getNodeValue()));
                }
                
            }
         return element;        
    }
    //按linkText遍历节点
    public static WebElement getlinkText(WebDriver driver,Node node) throws ParserConfigurationException, SAXException, IOException, BiffException{
            WebElement element=null;
                if(node.getNodeType()==Node.ELEMENT_NODE){
                    
                    if(node.getAttributes().getNamedItem("linkText")!=null){
                        element=driver.findElement(By.linkText(node.getAttributes().getNamedItem("linkText").getNodeValue()));
                    }
                    
                }
             return element;        
    }
    //按xpath遍历节点
    public static WebElement getXpath(WebDriver driver,Node node) throws ParserConfigurationException, SAXException, IOException, BiffException{
        WebElement element=null;
            if(node.getNodeType()==Node.ELEMENT_NODE){
                
                if(node.getAttributes().getNamedItem("xpath")!=null){
                    element=driver.findElement(By.xpath(node.getAttributes().getNamedItem("xpath").getNodeValue()));
                }
                
            }
         return element;        
}
    public static WebElement getTagName(WebDriver driver,Node node){
        WebElement element=null;
        if(node.getNodeType()==Node.ELEMENT_NODE){
            
            if(node.getAttributes().getNamedItem("tagName")!=null){
                element=driver.findElement(By.tagName(node.getAttributes().getNamedItem("tagName").getNodeValue()));
            }
            
        }
     return element;        
        
    }

}

测试数据与页面元素的同步

public class PostElementFactory {
    //获取XML节点的属性
     public static void showElement(WebDriver driver,Node node,Sheet sheet) throws ParserConfigurationException, SAXException, IOException, BiffException{
       //每一次访问就遍历了一次节点的该属性
        if(node.getNodeType()==Node.ELEMENT_NODE){
            
             WebElement element1=null;//PostElement.getID(driver, node);
             WebElement element2=null;//PostElement.getName(driver, node);
             WebElement element3=null;//PostElement.getClass(driver, node);
             WebElement element4=null;//PostElement.getlinkText(driver, node);
             WebElement element5=null;//PostElement.getcssSelector(driver, node);
             WebElement element6=null;//PostElement.getXpath(driver, node);
             WebElement element7=null;
       
             if((element1=PostElement.getID(driver, node))!=null)
                 PostElement.operator(driver,element1, node,sheet);
             else if(element1==null&&(element2=PostElement.getName(driver, node))!=null)
                 PostElement.operator(driver,element2, node,sheet);  
             else if(element1==null&&element2==null&&(element3=PostElement.getClass(driver, node))!=null)
                 PostElement.operator(driver,element3, node,sheet);
             else if(element1==null&&element2==null&&element3==null&&(element4=PostElement.getlinkText(driver, node))!=null)
                 PostElement.operator(driver,element4, node,sheet);
             else if(element1==null&&element2==null&&element3==null&&element4==null&&(element5=PostElement.getcssSelector(driver, node))!=null)
                 PostElement.operator(driver,element5, node,sheet);
             else if(element1==null&&element2==null&&element3==null&&element4==null&&element5==null&&(element6=PostElement.getXpath(driver, node))!=null)
                 PostElement.operator(driver,element6, node,sheet);
             else if(element1==null&&element2==null&&element3==null&&element4==null&&element5==null&&element6==null&&(element7=PostElement.getTagName(driver, node))!=null)
                 PostElement.operator(driver,element7, node,sheet);
                }
     }
     //对于Data和Element交互的处理
     public static void dealDataAndElement(WebDriver driver,String xml,String xls) throws BiffException, IOException, ParserConfigurationException, SAXException{
         Sheet sheet=DataHelper.DataOpen(xls);
         NodeList nodes=PostElement.doc(xml);
         for(int row=1;row<sheet.getRows();row++){
                    for (int i = 0, j = nodes.getLength(); i < j; i++) {
                        Node node = nodes.item(i);
                        PostElementFactory.showElement(driver, node, sheet);
                    }
                }
         }

}

                                      3>常用的逻辑类封装

页面元素table处理类的封装

public class DealTable {
    
    //tablexpath="//table[@class='table table-bordered table-striped table-hover']";
    //trxpath="/html/body/form[2]/table/thead/tr"
    static Log log = LogFactory.getLog(OSSMedCheck.class);
    
    //表格对象
    public static List<WebElement> dealwithTable(WebDriver driver,String tablexpath,String trxpath){
        
        WebElement element=driver.findElement(By.xpath(tablexpath));//先定位到table
        List<WebElement> rows = element.findElements(By.xpath(trxpath));//定位到table的每行
        return rows;
    }
    
    //行对象
    public static List<WebElement> dealwithRow_TD(WebElement theRow){
        List<WebElement> cells=null;
        if(theRow.findElements(By.tagName("td")).size()>0){
            cells = theRow.findElements(By.tagName("td"));
        }
        return cells;
    }
    public static List<WebElement> dealwithRow_TH(WebElement theRow){
        List<WebElement> cells=null;
        if(theRow.findElements(By.id("th")).size()>0){
            cells = theRow.findElements(By.tagName("th"));
        }
        return cells;
    }
    
    //单元格
    public static void dealwithCell(){
                
    }
    public static boolean checktablewithTD(WebElement cell,String TDText){
        
        boolean flag=false;
        flag=cell.getText().equals(TDText);
        return flag;
        
    }
    
    public static boolean checktablewithTH(WebElement cell,String THText){
        
        boolean flag=false;
        flag=cell.getText().equals(THText);
        return flag;
    }
    public static boolean OperateAboutTH(WebDriver driver,String xpathtable,String xpathtr,String THText[]){
        
        boolean flag=false;
        List<WebElement> rows=dealwithTable(driver,xpathtable,xpathtr);//定位到table
        WebElement theRow=rows.get(0);
        List<WebElement> cells=dealwithRow_TH(theRow);
        for(int cel=0;cel<cells.size();cel++){
            flag=cells.get(cel).getText().equals(THText[cel]);
        }
        return flag;
    }
    public static boolean OperateAboutTD(WebDriver driver,String xpathtable,String xpathtr,String TDText,int cel){
        boolean flag=false;
        List<WebElement> rows=dealwithTable(driver,xpathtable,xpathtr);
        for(int row=0;row<rows.size();row++){
            WebElement theRow=rows.get(row);
            if(theRow!=null){
                List<WebElement> cells=dealwithRow_TD(theRow);
                if(cells.size()>1){
                    flag=cells.get(cel).getText().equals(TDText);
                    if(flag==false){
                        break;
                    }
                }
                else {
                    log.info("按照状态"+TDText+"查询的记录为空");
                    flag=true;
                }
            }
        }
        return flag;
    }
    


}

类似处理稍后再贴吧,有点多了。

                                     

TestNG

1.TestNG来有规律地重整测试脚本,需要掌握的基础有:TestNG的标签的使用、testng.xml文件的使用

TestNG推荐文档:http://liulinxia02.blog.163.com/blog/static/268687720098713253574/

testng.xml的使用简单示范:

<?xml version="1.0" encoding="UTF-8"?>
<!-- 测试用例一:按照时间条件查询列表 -->
<suite name="Suite1" parallel="false">
  <test name="test1" >
    <classes>
        <class name="cases.OSSLogin">
            <methods>
                <include name="setUp"/>
                <include name="testOSSLogin"/>
            </methods>
        </class>
      <class name="cases.OSSMedCheck">
          <methods>
              <include name="testOSSMedCheckOne"/>
              <include name="testOSSMedCheckTwo"/>
              <include name="testOSSMedCheckThree"/>
              <include name="searchByDate"/>
          </methods>
      </class>
    </classes>
  </test>  
    <!-- 测试用例二:按照ID条件查询 -->
     <test name="test2">
     <classes>
         <class name="cases.OSSLogin">
            <methods>
                <include name="setUp"/>
                <include name="testOSSLogin"/>
            </methods>
        </class>
         <class name="cases.OSSMedCheck">
             <methods>
                 <include name="testOSSMedCheckOne"/>
                 <include name="testOSSMedCheckTwo"/>
                 <include name="testOSSMedCheckThree"/>
                 <include name="searchByID"/>
             </methods>
         </class>
     </classes>
  </test>
  <!-- 测试用例三:按照状态条件查询 -->
  <test name="test3">
      <classes>
         <class name="cases.OSSLogin">
            <methods>
                <include name="setUp"/>
                <include name="testOSSLogin"/>
            </methods>
        </class>
         <class name="cases.OSSMedCheck">
             <methods>
                 <include name="testOSSMedCheckOne"/>
                 <include name="testOSSMedCheckTwo"/>
                 <include name="testOSSMedCheckThree"/>
                 <include name="searchByStatus"/>
             </methods>
         </class>
     </classes>      
  </test>
  <!-- 测试用例四:导出提现审批列表 -->
  <test name="test4">
      <classes>
         <class name="cases.OSSLogin">
            <methods>
                <include name="setUp"/>
                <include name="testOSSLogin"/>
            </methods>
        </class>
         <class name="cases.OSSMedCheck">
             <methods>
                 <include name="testOSSMedCheckOne"/>
                 <include name="testOSSMedCheckTwo"/>
                 <include name="testOSSMedCheckThree"/>
                 <include name="downloadFolder"/>
             </methods>
         </class>
     </classes>      
  </test>
</suite> <!-- Suite -->

对于测试脚本的执行应该注意的是:

1.为增强代码的可重用性,脚本编码尽量模块化,这样在testng.xml中可自由组合成不同的测试用例

2.对于测试用例的起始,要注意driver对象的初始化,定义在BeforeTest标签处初始化会比较好,这样driver的开始和结束就是一个测试用例的开始和结束,比较有清晰

原文地址:https://www.cnblogs.com/LVAnny/p/TestNG.html