Selenium自動(dòng)化框架:數(shù)據(jù)驅(qū)動(dòng)神得、關(guān)鍵字驅(qū)動(dòng)和混合

微信公眾號(hào)-IT趕路人厘惦,專注分享與IT相關(guān)知識(shí),關(guān)注我哩簿,一起升職加薪宵蕉!

什么是Selenium框架酝静?

這個(gè) Selenium框架 是一種代碼結(jié)構(gòu),它使代碼維護(hù)變得簡(jiǎn)單而高效羡玛。如果沒有框架别智,用戶可以將“c”框架產(chǎn)生了一些有益的結(jié)果,比如增加了代碼可重用性稼稿、更高的可移植性薄榛、降低了腳本維護(hù)成本、更好的代碼可讀性等渺杉。

Selenium WebDriver主要?jiǎng)?chuàng)建了三種類型的框架來(lái)自動(dòng)化手動(dòng)測(cè)試用例

  • 數(shù)據(jù)驅(qū)動(dòng)測(cè)試框架

  • 關(guān)鍵字驅(qū)動(dòng)測(cè)試框架

  • 混合測(cè)試框架


    56.png

Selenium中的數(shù)據(jù)驅(qū)動(dòng)框架

Selenium中的數(shù)據(jù)驅(qū)動(dòng)框架 是一種將數(shù)據(jù)集與測(cè)試用例分開的方法蛇数。一旦數(shù)據(jù)集從測(cè)試用例中分離出來(lái),就可以很容易它用于從外部文件獲取測(cè)試用例和套件是越,如Excel耳舅、.csv、.xml或某些數(shù)據(jù)庫(kù)表倚评。


57.png

為了讀取或?qū)懭隕xcel浦徊,Apache提供了一個(gè)非常著名的庫(kù)POI。此庫(kù)足夠讀寫兩個(gè)庫(kù) XLS 和 xlsx Excel的文件格式天梧。

閱讀 XLS 文件盔性,一個(gè) HSSF 實(shí)現(xiàn)由POI庫(kù)提供。

閱讀 xlsx呢岗, XSSF 實(shí)現(xiàn) POI 庫(kù) 將是我們的選擇冕香。讓我們?cè)敿?xì)研究一下這些實(shí)現(xiàn)。

我們已經(jīng)在我們的上一個(gè)教程

Selenium中的關(guān)鍵字驅(qū)動(dòng)框架

Selenium中的關(guān)鍵字驅(qū)動(dòng)框架 是一種用于通過分隔常用函數(shù)和指令集的關(guān)鍵字來(lái)加速自動(dòng)化測(cè)試的方法后豫。用戶可以輕松地控制和指定他們想要測(cè)試的功能悉尾。

下面是完整框架的外觀


58.png

如所見,它是一個(gè)5步框架挫酿。讓我們逐步詳細(xì)地研究一下

步驟1)

  • 驅(qū)動(dòng)程序腳本Execute.java將調(diào)用ReadGuru99ExcelFile.java

  • ReadGuru99ExcelFile.java具有從Excel讀取數(shù)據(jù)的POI腳本

步驟2)

  • ReadGuru99ExcelFile.java將從TestCase.xlsx讀取數(shù)據(jù)

  • 這是床單的樣子-


    59.png
  • 框架將根據(jù)Excel文件中寫入的關(guān)鍵字對(duì)UI進(jìn)行操作构眯。

  • 例如,我們需要單擊“登錄”按鈕早龟。相應(yīng)地惫霸,我們的Excel將有一個(gè)關(guān)鍵字“點(diǎn)擊”。現(xiàn)在AUT可以在一個(gè)頁(yè)面上有數(shù)百個(gè)按鈕葱弟,為了標(biāo)識(shí)一個(gè)登錄按鈕壹店,在Excel中,我們將輸入對(duì)象名稱為loginButton芝加,輸入對(duì)象類型作為名稱(參見上圖中突出顯示的行)茫打。對(duì)象類型可以是XPath、名稱CSS或任何其他值

步驟3) ReadGuru99ExcelFile.java會(huì)將此數(shù)據(jù)傳遞給驅(qū)動(dòng)程序腳本Execute.java

步驟4)

  • 對(duì)于所有的UI web元素,我們需要?jiǎng)?chuàng)建一個(gè)對(duì)象存儲(chǔ)庫(kù)老赤,我們將在其中放置它們的元素定位符(如XPath、名稱制市、CSS路徑抬旺、類名等)。


    60.png
  • java(我們的驅(qū)動(dòng)程序腳本)將讀取整個(gè)對(duì)象存儲(chǔ)庫(kù)并將其存儲(chǔ)在一個(gè)變量中

  • 要讀取此對(duì)象存儲(chǔ)庫(kù)祥楣,我們需要一個(gè)具有g(shù)etObjectRepository方法的ReadObject類來(lái)讀取它开财。


    61.png

    注: 可能會(huì)想,我們?yōu)槭裁葱枰獎(jiǎng)?chuàng)建對(duì)象存儲(chǔ)庫(kù)误褪。對(duì)于對(duì)象存儲(chǔ)庫(kù)责鳍,只需在存儲(chǔ)庫(kù)中進(jìn)行一次更改。
    步驟5)

  • 驅(qū)動(dòng)程序會(huì)將數(shù)據(jù)從Excel&Object Repository傳遞到UIOperation類

  • UIOperation類具有執(zhí)行與關(guān)鍵字相對(duì)應(yīng)的動(dòng)作的功能兽间,如CLICK历葛、SETTEXT等…在EXCEL中提到

  • UIOperation類是一個(gè)Java語(yǔ)言類,該類具有對(duì)web元素執(zhí)行操作的代碼的實(shí)際實(shí)現(xiàn)嘀略。


    62.png

    整個(gè)項(xiàng)目將看起來(lái)像-


    63.png

    讓我們來(lái)看一個(gè)例子:

測(cè)試場(chǎng)景

object.properties

url= [http://www.itxiaonv.com/V4/](http://www.itxiaonv.com/V4/)

username=uid

password=password

title=barone

loginButton=btnLogin

resetButton=btnReset

ReadGuru99ExcelFile.java

package excelExportAndFileIO;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
public class ReadGuru99ExcelFile {
    public Sheet readExcel(String filePath,String fileName,String sheetName) throws IOException{
    //Create a object of File class to open xlsx file
    File file =    new File(filePath+"\\"+fileName);
    //Create an object of FileInputStream class to read excel file
    FileInputStream inputStream = new FileInputStream(file);
    Workbook guru99Workbook = null;
    //Find the file extension by spliting file name in substing and getting only extension name
    String fileExtensionName = fileName.substring(fileName.indexOf("."));
    //Check condition if the file is xlsx file
    if(fileExtensionName.equals(".xlsx")){
    //If it is xlsx file then create object of XSSFWorkbook class
    guru99Workbook = new XSSFWorkbook(inputStream);
    }
    //Check condition if the file is xls file
    else if(fileExtensionName.equals(".xls")){
        //If it is xls file then create object of XSSFWorkbook class
        guru99Workbook = new HSSFWorkbook(inputStream);
    }
    //Read sheet inside the workbook by its name
    Sheet guru99Sheet = guru99Workbook.getSheet(sheetName);
     return guru99Sheet;    
    }
}

ReadObject.java

package operation;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
public class ReadObject {
    Properties p = new Properties();
    public Properties getObjectRepository() throws IOException{
        //Read object repository file
        InputStream stream = new FileInputStream(new File(System.getProperty("user.dir")+"\\src\\objects\\object.properties"));
        //load all objects
        p.load(stream);
         return p;
    }
}

UIOperation.java

package operation;
import java.util.Properties;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
public class UIOperation {
    WebDriver driver;
    public UIOperation(WebDriver driver){
        this.driver = driver;
    }
    public void perform(Properties p,String operation,String objectName,String objectType,String value) throws Exception{
        System.out.println("");
        switch (operation.toUpperCase()) {
        case "CLICK":
            //Perform click
            driver.findElement(this.getObject(p,objectName,objectType)).click();
            break;
        case "SETTEXT":
            //Set text on control
            driver.findElement(this.getObject(p,objectName,objectType)).sendKeys(value);
            break;
        case "GOTOURL":
            //Get url of application
            driver.get(p.getProperty(value));
            break;
        case "GETTEXT":
            //Get text of an element
            driver.findElement(this.getObject(p,objectName,objectType)).getText();
            break;
        default:
            break;
        }
    }
    /
     * Find element BY using object type and value
     * @param p
     * @param objectName
     * @param objectType
     * @return
     * @throws Exception
     */
    private By getObject(Properties p,String objectName,String objectType) throws Exception{
        //Find by xpath
        if(objectType.equalsIgnoreCase("XPATH")){
            return By.xpath(p.getProperty(objectName));
        }
        //find by class
        else if(objectType.equalsIgnoreCase("CLASSNAME")){
            return By.className(p.getProperty(objectName));
        }
        //find by name
        else if(objectType.equalsIgnoreCase("NAME")){
            return By.name(p.getProperty(objectName));
        }
        //Find by css
        else if(objectType.equalsIgnoreCase("CSS")){
            return By.cssSelector(p.getProperty(objectName));
        }
        //find by link
        else if(objectType.equalsIgnoreCase("LINK")){
            return By.linkText(p.getProperty(objectName));
        }
        //find by partial link
        else if(objectType.equalsIgnoreCase("PARTIALLINK")){
            return By.partialLinkText(p.getProperty(objectName));
        }else
        {
            throw new Exception("Wrong object type");
        }
    }
}

ExecuteTest.java

package testCases;
import java.util.Properties;
import operation.ReadObject;
import operation.UIOperation;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.testng.annotations.Test;
import excelExportAndFileIO.ReadGuru99ExcelFile;
public class ExecuteTest {
@Test
    public void testLogin() throws Exception {
        // TODO Auto-generated method stub
WebDriver webdriver = new FirefoxDriver();
ReadGuru99ExcelFile file = new ReadGuru99ExcelFile();
ReadObject object = new ReadObject();
Properties allObjects = object.getObjectRepository();
UIOperation operation = new UIOperation(webdriver);
//Read keyword sheet
Sheet guru99Sheet = file.readExcel(System.getProperty("user.dir")+"\\","TestCase.xlsx" , "KeywordFramework");
//Find number of rows in excel file
    int rowCount = guru99Sheet.getLastRowNum()-guru99Sheet.getFirstRowNum();
    //Create a loop over all the rows of excel file to read it
    for (int i = 1; i < rowCount+1; i++) {
        //Loop over all the rows
        Row row = guru99Sheet.getRow(i);
        //Check if the first cell contain a value, if yes, That means it is the new testcase name
        if(row.getCell(0).toString().length()==0){
        //Print testcase detail on console
            System.out.println(row.getCell(1).toString()+"----"+ row.getCell(2).toString()+"----"+
            row.getCell(3).toString()+"----"+ row.getCell(4).toString());
        //Call perform function to perform operation on UI
            operation.perform(allObjects, row.getCell(1).toString(), row.getCell(2).toString(),
                row.getCell(3).toString(), row.getCell(4).toString());
     }
        else{
            //Print the new testcase name when it started
                System.out.println("New Testcase->"+row.getCell(0).toString() +" Started");
            }
        }
    }
}

執(zhí)行后恤溶,輸出將如下所示-


64.png

下載本教程中演示的Selenium項(xiàng)目文件

混合框架

混合框架 In Selenium是一個(gè)概念,在這個(gè)概念中帜羊,我們既利用了關(guān)鍵字驅(qū)動(dòng)框架的優(yōu)勢(shì)咒程,也利用了數(shù)據(jù)驅(qū)動(dòng)框架的優(yōu)勢(shì)。它是一個(gè)易于使用的框架讼育,允許手動(dòng)測(cè)試人員只需查看關(guān)鍵字帐姻、測(cè)試數(shù)據(jù)和對(duì)象存儲(chǔ)庫(kù)就可以創(chuàng)建測(cè)試用例,而無(wú)需在框架中編碼奶段。

在這里饥瓷,對(duì)于關(guān)鍵字,我們將使用Excel文件來(lái)維護(hù)測(cè)試用例忧饭,而對(duì)于測(cè)試數(shù)據(jù)扛伍,我們可以使用Data、ProviderTestNG框架词裤。


65.png

在我們的混合框架中刺洒,我們不需要更改關(guān)鍵字驅(qū)動(dòng)框架中的任何內(nèi)容,這里我們只需要將ExecuteTest.java文件替換為Hybridge ExecuteTest.java文件吼砂。


66.png

此Hybridge ExecuteTest文件包含由數(shù)據(jù)提供程序概念驅(qū)動(dòng)的關(guān)鍵字的所有代碼逆航。

混合框架的完整圖示如下所示


67.png

HybridExecuteTest.java

package testCases;
import java.io.IOException;
import java.util.Properties;
import operation.ReadObject;
import operation.UIOperation;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import excelExportAndFileIO.ReadGuru99ExcelFile;
public class HybridExecuteTest {
    WebDriver webdriver = null;
@Test(dataProvider="hybridData")
    public void testLogin(String testcaseName,String keyword,String objectName,String objectType,String value) throws Exception {
        // TODO Auto-generated method stub
    if(testcaseName!=null&&testcaseName.length()!=0){
    webdriver=new FirefoxDriver();
    }
ReadObject object = new ReadObject();
Properties allObjects = object.getObjectRepository();
UIOperation operation = new UIOperation(webdriver);
    //Call perform function to perform operation on UI
            operation.perform(allObjects, keyword, objectName,
                objectType, value);
    }
@DataProvider(name="hybridData")
    public Object[][] getDataFromDataprovider() throws IOException{
    Object[][] object = null;
    ReadGuru99ExcelFile file = new ReadGuru99ExcelFile();
//Read keyword sheet
Sheet guru99Sheet = file.readExcel(System.getProperty("user.dir")+"\\","TestCase.xlsx" , "KeywordFramework");
//Find number of rows in excel file
    int rowCount = guru99Sheet.getLastRowNum()-guru99Sheet.getFirstRowNum();
    object = new Object[rowCount][5];
    for (int i = 0; i < rowCount; i++) {
        //Loop over all the rows
        Row row = guru99Sheet.getRow(i+1);
        //Create a loop to print cell values in a row
        for (int j = 0; j < row.getLastCellNum(); j++) {
            //Print excel data in console
            object[i][j] = row.getCell(j).toString();
        }
    }
    System.out.println("");
     return object;    
    }
}

總結(jié):

  • 我們可以使用Selenium WebDriver創(chuàng)建三種類型的測(cè)試框架。

  • 它們是數(shù)據(jù)驅(qū)動(dòng)渔肩、關(guān)鍵字驅(qū)動(dòng)和混合測(cè)試框架因俐。

  • 我們可以使用TestNG的數(shù)據(jù)提供程序來(lái)實(shí)現(xiàn)數(shù)據(jù)驅(qū)動(dòng)框架。

  • 在關(guān)鍵字驅(qū)動(dòng)框架中,關(guān)鍵字被寫入一些外部文件抹剩,如EXCEL文件撑帖,Java代碼將調(diào)用該文件并執(zhí)行測(cè)試用例。

  • 該混合框架是關(guān)鍵字驅(qū)動(dòng)和數(shù)據(jù)驅(qū)動(dòng)的混合框架澳眷。

26322751-8bd00fde1a719aa1.jpg
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末胡嘿,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子钳踊,更是在濱河造成了極大的恐慌衷敌,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,470評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件拓瞪,死亡現(xiàn)場(chǎng)離奇詭異缴罗,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)祭埂,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,393評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門面氓,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人沟堡,你說(shuō)我怎么就攤上這事侧但。” “怎么了航罗?”我有些...
    開封第一講書人閱讀 162,577評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵禀横,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我粥血,道長(zhǎng)柏锄,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,176評(píng)論 1 292
  • 正文 為了忘掉前任复亏,我火速辦了婚禮趾娃,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘缔御。我一直安慰自己抬闷,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,189評(píng)論 6 388
  • 文/花漫 我一把揭開白布耕突。 她就那樣靜靜地躺著笤成,像睡著了一般。 火紅的嫁衣襯著肌膚如雪眷茁。 梳的紋絲不亂的頭發(fā)上炕泳,一...
    開封第一講書人閱讀 51,155評(píng)論 1 299
  • 那天,我揣著相機(jī)與錄音上祈,去河邊找鬼培遵。 笑死浙芙,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的籽腕。 我是一名探鬼主播嗡呼,決...
    沈念sama閱讀 40,041評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼节仿!你這毒婦竟也來(lái)了晤锥?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,903評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤廊宪,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后女轿,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體箭启,經(jīng)...
    沈念sama閱讀 45,319評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,539評(píng)論 2 332
  • 正文 我和宋清朗相戀三年蛉迹,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了傅寡。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,703評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡北救,死狀恐怖荐操,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情珍策,我是刑警寧澤托启,帶...
    沈念sama閱讀 35,417評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站攘宙,受9級(jí)特大地震影響屯耸,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜蹭劈,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,013評(píng)論 3 325
  • 文/蒙蒙 一疗绣、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧铺韧,春花似錦多矮、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,664評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至前酿,卻和暖如春患雏,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背罢维。 一陣腳步聲響...
    開封第一講書人閱讀 32,818評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工淹仑, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留丙挽,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,711評(píng)論 2 368
  • 正文 我出身青樓匀借,卻偏偏與公主長(zhǎng)得像颜阐,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子吓肋,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,601評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容