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

1、原理及特色java

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

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

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

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

2、準備

使用工具:eclipse微信

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

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

3、框架構思

一、編寫腳本eclipse

首先咱們來寫一個登錄開源中國的腳本工具

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();
                }
}

二、腳本分析

這是登錄的場景

操做步驟

第一步:啓動瀏覽器

第二步:輸入網址

第四步:點擊登陸

第五步:輸入用戶名

第六步:輸入密碼

第七步:點擊登陸按鈕

第八步:點擊退出

第九步:關閉瀏覽器

三、使用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;
        }
}

四、新建一個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();
    }
}

五、修改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();
                    }
                }
            }
}

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

4、結構優化

一、優化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();
                        }
                    }
                }
            }
}

二、將程序中的常量統一管理

例如:網頁的地址,帳戶、密碼,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";
}

三、增長對象庫

下面咱們看一下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中讀取的

 

 

四、增長測試場景

從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;
					}
					
				}
				
								
			}

 

五、增長測試結果

在Excel中新增一列Resut

 

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

5、小結

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

        

代碼地址:http://git.oschina.net/hellotester/SeleniumKeywordDrive

 

歡迎你們關注微信公衆號進行交流

相關文章
相關標籤/搜索