UI自動化測試框架之Selenium關鍵字驅動 (轉)


 

摘要

自動化測試框架demo,用關鍵字的形式將測試邏輯封裝在數據文件中,測試工具解釋這些關鍵字即可對其應用自動化

一、原理及特點

1.   關鍵字驅動測試是數據驅動測試的一種改進類型

2.    主要關鍵字包括三類:被操作對象(Item)、操作(Operation)和值(value),用面向對象形式可將其表現為Item.Operation(Value)

3.   將測試邏輯按照這些關鍵字進行分解,形成數據文件。

4.    用關鍵字的形式將測試邏輯封裝在數據文件中,測試工具只要能夠解釋這些關鍵字即可對其應用自動化

二、准備

使用工具:eclipse

用到的第三方jar包:poi.jar(操作excel);selenium.jar

理解難點:java反射機制;逐步分層

三、框架構思

1、編寫腳本

首先我們來寫一個登陸開源中國的腳本

public class Login_Script {             public static WebDriver driver=null;             public static void main(String []agrs) throws InterruptedException{ //                啟動火狐瀏覽器                 driver= new FirefoxDriver(); //                最大化                 driver.manage().window().maximize(); //                打開開源中國網址                 driver.get("http://www.oschina.net/"); //                點擊登錄                 driver.findElement(By.xpath("//*[@id='OSC_Userbar']/a[1]")).click(); //                輸入用戶名                 driver.findElement(By.xpath("//*[@id='f_email']")).sendKeys("XXXXXXB"); //                輸入密碼                 driver.findElement(By.xpath("//*[@id='f_pwd']")).sendKeys("XXXXXXXA"); //                點擊登錄按鈕 //                driver.findElement(By.xpath("//*[@id='login_osc']/table/tbody/tr[7]/td/input")).click(); //                Thread.sleep(30); //                點擊退出按鈕                 driver.findElement(By.xpath("//*[@id='OSC_Userbar']/a[3]")).click(); //                關閉瀏覽器                 driver.quit();                 } }
2、腳本分析

這是登陸的場景

操作步驟

第一步:啟動瀏覽器

第二步:輸入網址

第四步:點擊登錄

第五步:輸入用戶名

第六步:輸入密碼

第七步:點擊登錄按鈕

第八步:點擊退出

第九步:關閉瀏覽器

3、使用excel

建立一個excel

在java中創建一個操作excel的類 ,主要實現是對excel的讀和寫,主要代碼如下:

public class ExcelUtils {         public static HSSFSheet ExcelSheet;         public static HSSFWorkbook    ExcelBook;         public static HSSFRow Row;         public static HSSFCell    Cell;         public static void setExcelFile(String Path,String    SheetName) throws Exception{             FileInputStream    ExcelFile=new FileInputStream(Path);             ExcelBook=new HSSFWorkbook(ExcelFile);             ExcelSheet=ExcelBook.getSheet(SheetName);                 }         public static void setCellData(String Result,  int RowNum, int ColNum,String Path) throws Exception{               Row  = ExcelSheet.getRow(RowNum);             Cell = Row.getCell(ColNum, Row.RETURN_BLANK_AS_NULL);             if (Cell == null) {                 Cell = Row.createCell(ColNum);                 Cell.setCellValue(Result);                 } else {                     Cell.setCellValue(Result);                 }             FileOutputStream fileOut = new FileOutputStream(Path);             ExcelBook.write(fileOut);             fileOut.flush();             fileOut.close();         }         public static String getCellDate(int RowNum,int CloNum){             Cell=ExcelSheet.getRow(RowNum).getCell(CloNum);             String cellData=Cell.getStringCellValue();             return cellData;         } }
4、新建一個ActionKeyWords類
public class ActionKeyWords {     public static WebDriver driver=null; //    啟動瀏覽器並最大化     public static void OpenBrowser (){         driver= new FirefoxDriver();         driver.manage().window().maximize();     } //    打開開源中國網址     public static void Navigate (){         driver.get("http://www.oschina.net/");     } //    點擊登錄     public static void Login_Click (){         driver.findElement(By.xpath("//*[@id='OSC_Userbar']/a[1]")).click();     } //    輸入用戶名     public static void Input_Name (){         driver.findElement(By.xpath("//*[@id='f_email']")).sendKeys("XXXXXXA");     } //    輸入密碼     public static void Input_Password (){         driver.findElement(By.xpath("//*[@id='f_pwd']")).sendKeys("XXXXXXB");     } //    點擊登錄按鈕     public static void Login_Button (){         driver.findElement(By.xpath("//*[@id='login_osc']/table/tbody/tr[7]/td/input")).click();     }     //    點擊退出按鈕     public static void Logout_Click (){         driver.findElement(By.xpath("//*[@id='OSC_Userbar']/a[3]")).click();     } //    關閉瀏覽器     public static void CloseBrowser (){         driver.quit();     } }
5、修改Login_Script腳本.
public class Login_Script {             public static void main(String []agrs) throws Exception{                 ExcelUtils.setExcelFile("D:\\data\\TestData.xls", "steps");                 ActionKeyWords actionKeyWords= new ActionKeyWords();                 String Keywords=null;                 for(int RowNum=1;RowNum<=ExcelUtils.getLastRowNums();RowNum++){                     Keywords=ExcelUtils.getCellDate(RowNum, 3);                     if(Keywords.trim().equals("OpenBrowser")){                         actionKeyWords.OpenBrowser();                     }else if(Keywords.trim().equals("Navigate")){                         actionKeyWords.Navigate();                     }else if(Keywords.trim().equals("Login_Click")){                         actionKeyWords.Login_Click();                     }else if(Keywords.trim().equals("Input_Name")){                         actionKeyWords.Input_Name();                     }else if(Keywords.trim().equals("Input_Password")){                         actionKeyWords.Input_Password();                     }else if(Keywords.trim().equals("Login_Button")){                         actionKeyWords.Login_Button();                     }else if(Keywords.trim().equals("Logout_Click")){                         actionKeyWords.Logout_Click();                     }else if(Keywords.trim().equals("CloseBrowser")){                         actionKeyWords.CloseBrowser();                     }                 }             } }

這樣代碼的框架就基本已經搭建起來了,代碼結構如下:

四、結構優化

1、優化Login_Script 類中的代碼

注:這里用到了反射機制

 public class Login_Script {             public static ActionKeyWords actionKeyWords;             public static String Keywords=null;             public static Method[] method;             public Login_Script(){                 actionKeyWords= new ActionKeyWords();                 method=actionKeyWords.getClass().getMethods();             }             public static void main(String []agrs) throws Exception{                 ExcelUtils.setExcelFile("D:\\data\\TestData.xls", "steps");                 new Login_Script();                 for(int RowNum=1;RowNum<=ExcelUtils.getLastRowNums();RowNum++){                     Keywords=ExcelUtils.getCellDate(RowNum, 3);                     login_action();                 }             }             public static void login_action(){                 for(int i=0;i<method.length;i++){ //                    System.out.println(method[i].getName()+"     "+actionKeyWords+Keywords);                     if(method[i].getName().trim().equals(Keywords)){                         try {                             method[i].invoke(actionKeyWords);                         } catch (IllegalAccessException e) {                             // TODO Auto-generated catch block                             e.printStackTrace();                         } catch (IllegalArgumentException e) {                             // TODO Auto-generated catch block                             e.printStackTrace();                         } catch (InvocationTargetException e) {                             // TODO Auto-generated catch block                             e.printStackTrace();                         }                     }                 }             } }
2、將程序中的常量統一管理

例如:網頁的地址,賬戶、密碼,excel路徑,這里我們在文件下面建立一個

public class Contants {     public static  String url="http://www.oschina.net/";     public static String excelFile="D:\\data\\";     public static String excelName="TestData.xls";     public static String excelSheet="steps";     public static int excelKWCloNum=3;     public static String userName="XXXXXXXA";     public static String userPassword="XXXXXB"; }
3、增加對象庫

下面我們看一下ActionKeyWords類中定位元素的路徑 是在代碼里面的,如果每次去修改的定位路徑的是時候都要修改代碼,為了便於維護,我們將這些元素的對象放在一個文件中,同時我們在Excel增加一列 Page Objects,這樣程序根據Excel中的Page Objects,去文件中讀取相應的元素,這里我們增加一個類OrpUtil,讀取元素的對象 

# Home Page Objects Userbar_login=//*[@id='OSC_Userbar']/a[1] Userbar_logout=//div[@id='OSC_Userbar']/a[3] #Login Page Objects Input_name=//*[@id='f_email'] Input_password=//*[@id='f_pwd'] Login_button=//*[@id='login_osc']/table/tbody/tr[7]/td/input
//OrpUtil類 public class OrpUtil {     public static String  readValue(String a){         Properties pro=new Properties();         String popath=Contants.ObjectReUrl;         String value=null;         try {             InputStream in =new BufferedInputStream(new FileInputStream(popath));             pro.load(in);             value=pro.getProperty(a);         } catch (FileNotFoundException e) {             // TODO Auto-generated catch block             e.printStackTrace();         }catch (IOException e) {             // TODO Auto-generated catch block             e.printStackTrace();         }         return value;     } }

優化后的ActionKeyWords類

public class ActionKeyWords {     public static WebDriver driver=null; //    啟動瀏覽器並最大化     public static void OpenBrowser (String OR){         System.setProperty("webdriver.chrome.driver", ".//server//chromedriver.exe");         driver= new ChromeDriver();         driver.manage().window().maximize();     } //    打開開源中國網址     public static void Navigate (String OR){         driver.get(Contants.url);     } //    點擊登錄     public static void Login_Click (String OR){         driver.findElement(By.xpath(OrpUtil.readValue(OR))).click();     } //    輸入用戶名     public static void Input_Name (String OR){         driver.findElement(By.xpath(OrpUtil.readValue(OR))).clear();         driver.findElement(By.xpath(OrpUtil.readValue(OR))).sendKeys(Contants.userName);     } //    輸入密碼     public static void Input_Password (String OR){         driver.findElement(By.xpath(OrpUtil.readValue(OR))).click();         driver.findElement(By.xpath(OrpUtil.readValue(OR))).sendKeys(Contants.userPassword);     } //    點擊登錄按鈕     public static void Login_Button (String OR){         driver.findElement(By.xpath(OrpUtil.readValue(OR))).click();     }     //    點擊退出按鈕     public static void Logout_Click (String OR){         try {             Thread.sleep(300);             driver.findElement(By.xpath(OrpUtil.readValue(OR))).click();         } catch (InterruptedException e) {             // TODO Auto-generated catch block             e.printStackTrace();         }     } //    關閉瀏覽器     public static void CloseBrowser (String OR){         driver.quit();     } }

這個OR的值是從Excel中讀取的

 

 

4、增加測試場景

從Excel中我們可以看到,這操作是對應的用例編寫中的我們的操作步驟,在用例設計的時候還有測試場景和結果,這里

我們先增加個場景在EXCEL中增加一個名稱為Suite的Sheet頁

我們程序的運行邏輯是循環讀取Suite頁中的Runmode,當為YES時根據對應的TestSuiteID去讀取對應的Steps頁中的操作在步驟,進行運行

public static void main(String []agrs) throws Exception{ ExcelUtils.setExcelFile(Contants.excelFile+Contants.excelName ); new Login_Script(); bResult = true; // 循環讀取suitSheet里面的值,找出運行的場景 for(int j=1;j<=ExcelUtils.getLastRowNums(Contants.suitSheet);j++){ String Runmode=ExcelUtils.getCellDate(j, Contants.suitRunmode,Contants.suitSheet); String suitTestSuiteId=ExcelUtils.getCellDate(j, Contants.suitTestSuiteId,Contants.suitSheet); int sRowNum; if(Runmode.equals("YES")){ // 根據stepTestSuiteId在caseSheet中循環查找相對應的執行步驟 for(sRowNum=1;sRowNum<=ExcelUtils.getLastRowNums(Contants.caseSheet);sRowNum++){ String stepTestSuiteId=ExcelUtils.getCellDate(sRowNum, Contants.stepTestSuiteId,Contants.caseSheet); System.out.println(ExcelUtils.getCellDate(sRowNum, Contants.excelKWCloNum,Contants.caseSheet)); if(stepTestSuiteId.trim().equals(suitTestSuiteId)){ Keywords=ExcelUtils.getCellDate(sRowNum, Contants.excelKWCloNum,Contants.caseSheet); r=ExcelUtils.getCellDate(sRowNum, Contants.excelPOCloNum,Contants.caseSheet); login_action(sRowNum); if(bResult == false){ ExcelUtils.setCellData(Contants.fail, j, Contants.suitResult,Contants.excelFile+Contants.excelName, Contants.suitSheet); } } } if(bResult == true){ ExcelUtils.setCellData(Contants.pass, j, Contants.suitResult,Contants.excelFile+Contants.excelName, Contants.suitSheet); } }else{ System.out.println("沒有要執行的用例"); break; } } }

 

5、增加測試結果

在Excel中新增一列Resut

 

在Login_Script中定義一個boolean類型的變量bResult,默認是true在各個地方try,,cacth,當出現異常的時候在bResult賦值為false,在Excel工具類中增加一個寫入excel值得方法

五、小結

這樣我們的關鍵字驅動框架就初步搭好了,下面我們回歸一下基本思路:

        

轉自:http://my.oschina.net/hellotest/blog/531932


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM