Selenium WebDriver 數據驅動測試框架


Selenium WebDriver 數據驅動測試框架,以QQ郵箱添加聯系人為示例,測試框架結構如下圖:

ObjectMap.java

/**
 * 使用配置文件存儲測試頁面上的定位和定位表達式,做到定位數據和程序的分離
 */
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;
import org.openqa.selenium.By;

public class ObjectMap {

    Properties properties;

    public ObjectMap(String propFile) {
        properties = new Properties();
        try {
            FileInputStream in = new FileInputStream(propFile);
            properties.load(in);
            in.close();
        } catch (IOException e) {
            System.out.println("讀取對象文件出錯");
            e.printStackTrace();
        }
    }

    public By getLocator(String ElementNameInpopFile) throws Exception {
        // 根據變量ElementNameInpopFile,從屬性配置文件中讀取對應的配置對象
        String locator = properties.getProperty(ElementNameInpopFile);
        
        // 將配置對象中的定位類型存儲到locatorType變量,將定位表達式的值存儲到locatorValue變量中
        String locatorType = locator.split(":")[0];
        String locatorValue = locator.split(":")[1];
        
        // 在Eclipse中的配置文件均默認為ISO-8859-1編碼存儲,使用getBytes方法可以將字符串編碼轉換為UTF-8編碼,以此來解決在配置文件讀取中文亂碼的問題
        locatorValue = new String(locatorValue.getBytes("ISO-8859-1"), "UTF-8");
        // 輸出locatorType變量值和locatorValue變量值,驗證是否賦值正確
        System.out.println("獲取的定位類型:" + locatorType + "\t 獲取的定位表達式:" + locatorValue);
        
        // 根據locatorType的變量值內容判斷返回何種定位方式的By對象
        if (locatorType.toLowerCase().equals("id")) {
            return By.id(locatorValue);
        } else if (locatorType.toLowerCase().equals("name")) {
            return By.name(locatorValue);
        } else if ((locatorType.toLowerCase().equals("classname")) || (locatorType.toLowerCase().equals("class"))) {
            return By.className(locatorValue);
        } else if ((locatorType.toLowerCase().equals("tagname")) || (locatorType.toLowerCase().equals("tag"))) {
            return By.className(locatorValue);
        } else if ((locatorType.toLowerCase().equals("linktext")) || (locatorType.toLowerCase().equals("link"))) {
            return By.linkText(locatorValue);
        } else if (locatorType.toLowerCase().equals("partiallinktext")) {
            return By.partialLinkText(locatorValue);
        } else if ((locatorType.toLowerCase().equals("cssselector")) || (locatorType.toLowerCase().equals("css"))) {
            return By.cssSelector(locatorValue);
        } else if (locatorType.toLowerCase().equals("xpath")) {
            return By.xpath(locatorValue);
        } else {
            throw new Exception("輸入的 locator type 未在程序中被定義:" + locatorType);
        }
    }
}

Constant.java

public class Constant {
    
    //測試網址常量
    public static final String URL = "http://mail.qq.com";

    //測試數據EXCEL路徑
    public static final String TestDataExcelFilePath = "f:\\QQ郵箱的測試數據.xlsx";
    
    //EXCEL測試數據sheet名稱
    public static final String  TestDataExcelFileSheet = "新建聯系人測試用例";
}

ExcelUntil.java

package until;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

public class ExcelUntil {

    private static XSSFSheet excelWSheet;
    private static XSSFWorkbook excelWBook;
    private static XSSFCell cell;
    private static XSSFRow row;
    
    //指定要操作的excel文件的路徑及sheet名稱
    public static void setExcelFile(String path,String sheetName) throws Exception{
        
        FileInputStream excelFile;
        try {
            excelFile = new FileInputStream(path);
            excelWBook = new XSSFWorkbook(excelFile);
            excelWSheet = excelWBook.getSheet(sheetName);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    //讀取excel文件指定單元格數據(此方法只針對.xlsx后輟的Excel文件)
    public static String getCellData(int rowNum,int colNum) throws Exception{
        try {
            //獲取指定單元格對象
            cell = excelWSheet.getRow(rowNum).getCell(colNum);
            //獲取單元格的內容
            //如果為字符串類型,使用getStringCellValue()方法獲取單元格內容,如果為數字類型,則用getNumericCellValue()獲取單元格內容
            String cellData = cell.getStringCellValue();
            return cellData;    
        } catch (Exception e) {
            return "";
        }
    }
    
    //在EXCEL的執行單元格中寫入數據(此方法只針對.xlsx后輟的Excel文件) rowNum 行號,colNum 列號
    public static void setCellData(int rowNum,int colNum,String Result) throws Exception{
        try {
            //獲取行對象
            row = excelWSheet.getRow(rowNum);
            //如果單元格為空,則返回null
            cell = row.getCell(colNum);
            if(cell == null){
                cell=row.createCell(colNum);
                cell.setCellValue(Result);
            }else{
                cell.setCellValue(Result);
            }
            FileOutputStream out = new FileOutputStream(Constant.TestDataExcelFilePath);
            //將內容寫入excel中
            excelWBook.write(out);
            out.flush();
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    //從EXCEL文件中獲取測試數據
    public static Object[][] getTestData(String excelFilePath,String sheetName) throws IOException{
        //聲明一個file文件對象
        File file = new File(excelFilePath);
        //創建一個輸入流
        FileInputStream in = new FileInputStream(file);
        //聲明workbook對象
        Workbook workbook = null;
        //判斷文件擴展名
        String fileExtensionName = excelFilePath.substring(excelFilePath.indexOf("."));
        if(fileExtensionName.equals(".xlsx")){
            workbook = new XSSFWorkbook(in);
        }else {
            workbook = new HSSFWorkbook(in);
        }
        
        //獲取sheet對象
        Sheet sheet = workbook.getSheet(sheetName);
        //獲取sheet中數據的行數,行號從0始
        int rowCount = sheet.getLastRowNum()-sheet.getFirstRowNum();
        
        List<Object[]> records = new ArrayList<Object[]>();
        //讀取數據(省略第一行表頭)
        for(int i=1; i<rowCount+1; i++){
            //獲取行對象
            Row row = sheet.getRow(i);
            System.out.println(">>>>>>>>>>> "+ row.getLastCellNum());
            //聲明一個數組存每行的測試數據,excel最后兩列不需傳值
            String[] fields = new String[row.getLastCellNum()-2];
            //excel倒數第二列為Y,表示數據行要被測試腳本執行,否則不執行
            if(row.getCell(row.getLastCellNum()-2).getStringCellValue().equals("Y")){
                for(int j=0; j<row.getLastCellNum()-2; j++){
                    //判斷單元格數據是數字還是字符
                    //fields[j] = row.getCell(j).getCellTypeEnum() == CellType.STRING ? row.getCell(j).getStringCellValue() : ""+row.getCell(j).getNumericCellValue(); 
                    fields[j] = row.getCell(j).getCellType() == CellType.STRING ? row.getCell(j).getStringCellValue() : ""+row.getCell(j).getNumericCellValue(); 
                }
                records.add(fields);
            }
        }
        //將list轉為Object二維數據
        Object[][] results = new Object[records.size()][];
        //設置二維數據每行的值,每行是一個object對象
        for(int i=0; i<records.size(); i++){
            results[i]=records.get(i);
        }
        return results;
    }
    
    public static int getLastColumnNum(){
        //返回數據文件最后一列的列號,如果有12列則返回11
        return excelWSheet.getRow(0).getLastCellNum()-1;
    }
}

Log.java

package until;

import org.apache.log4j.Logger;

public class Log {

    // 初始化Log4j日志
    private static Logger Log = Logger.getLogger(Log.class.getName());

    // 打印測試用例開頭的日志
    public static void startTestCase(String sTestCaseName) {
        Log.info("------------------ " + sTestCaseName + "  " +"開始執行 ------------------");
    }

    //打印測試用例結束的日志
    public static void endTestCase(String sTestCaseName) {
        Log.info("------------------ " + sTestCaseName + "  " +"測試執行結束 ---------------");

    }

    public static void info(String message) {
        Log.info(message);
    }

    public static void warn(String message) {
        Log.warn(message);
    }

    public static void error(String message) {
        Log.error(message);
    }

    public static void fatal(String message) {
        Log.fatal(message);
    }

    public static void debug(String message) {
        Log.debug(message);
    }

}

 

LoginPage.java

package pageobject;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;

import until.ObjectMap;

public class LoginPage {
    
    private WebElement element = null;
    //指定頁面元素定位表達式配置文件的絕對路徑
    private ObjectMap objectMap = new ObjectMap("F:\\workspace\\TestNGProj\\ObjectMap.properties");
    private WebDriver driver;
    
    public LoginPage(WebDriver driver){
        this.driver = driver;
    }
    
    //返回登錄頁面中的用戶名輸入框頁面元素對象
    public WebElement username() throws Exception{
        element =driver.findElement(objectMap.getLocator("QQ.Email.username"));
        return element;
    }
    
    //返回登錄頁面中的密碼輸入框頁面元素對象
    public WebElement password() throws Exception {
        element = driver.findElement(objectMap.getLocator("QQ.Email.password"));
        return element;
    }
    
    //返回登錄頁面中的登錄按鈕頁面元素對象
    public WebElement login_button() throws Exception {
        element = driver.findElement(objectMap.getLocator("QQ.Email.login_button"));
        return element;
    } 
}

 

HomePage.java

package pageobject;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;

import until.ObjectMap;

public class HomePage {
    
    private WebElement element = null;
    private ObjectMap objectMap = new ObjectMap("F:\\workspace\\TestNGProj\\ObjectMap.properties");
    private WebDriver driver;
    
    public HomePage(WebDriver driver){
        this.driver = driver;
    }
    
    //獲取登錄后主頁的“通訊錄”鏈接
    public WebElement addressLink() throws Exception{
        element = driver.findElement(objectMap.getLocator("QQEmail.homepage.address_book"));
        return element;
    }
}

 

AddressBookPage.java

package pageobject;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;

import until.ObjectMap;

public class AddressBookPage {
    
    private WebElement element = null;
    private ObjectMap objectMap = new ObjectMap("F:\\workspace\\TestNGProj\\ObjectMap.properties");
    private WebDriver driver;
    
    public AddressBookPage(WebDriver driver){
        this.driver = driver;
    }
    
    //獲取新建聯系人按鈕
    public WebElement addContactButton() throws Exception{
        element = driver.findElement(objectMap.getLocator("QQEmail.addressBook.add_button"));
        return element;
    }
    
    //新建聯系人頁面姓名輸入框
    public WebElement addContactName()throws Exception{
        element = driver.findElement(objectMap.getLocator("QQEmail.addressBook.add_Contact"));
        return element;
    }
    
    //新建聯系人頁面郵件輸入框
    public WebElement addContactEmail() throws Exception{
        element = driver.findElement(objectMap.getLocator("QQEmail.addressBook.add_email"));
        return element;
    }
    
    //新建聯系人頁面電話輸入框
    public WebElement addContactTell() throws Exception{
        element = driver.findElement(objectMap.getLocator("QQEmail.addressBook.add_tell"));
        return element;
    }
    
    //新建聯系人頁面國家輸入框
    public WebElement addContactCounty() throws Exception{
        element = driver.findElement(objectMap.getLocator("QQEmail.addressBook.add_country"));
        return element;
    }
    
    //新建聯系人頁面省份輸入框
    public WebElement addContactProvince() throws Exception{
        element = driver.findElement(objectMap.getLocator("QQEmail.addressBook.add_province"));
        return element;
    }
    
    //新建聯系人頁面城市輸入框
    public WebElement addContactCity() throws Exception{
        element = driver.findElement(objectMap.getLocator("QQEmail.addressBook.add_city"));
        return element;
    }
    
    //新建聯系人頁面保存按鈕
    public WebElement addContactSaveButton() throws Exception{
        element = driver.findElement(objectMap.getLocator("QQEmail.addressBook.save_button"));
        return element;
    }
}

 

LoginAction.java

package appmodules;

import org.openqa.selenium.WebDriver;
import org.testng.annotations.Test;
import pageobject.LoginPage;
import until.Log;

/**
 * 登錄方法的封裝,方便其他測試腳本的調用
 *
 */
public class LoginAction {

    public static void execute(WebDriver driver,String userName,String passWord) throws Exception{
        Log.info("訪問網址:http://mail.qq.com");
        driver.get("http://mail.qq.com");
        driver.switchTo().frame("login_frame");
        LoginPage loginPage = new LoginPage(driver);
        loginPage.username().clear();
        Log.info("在QQ郵箱登錄頁面的用戶名輸入框中輸入 "+userName);
        loginPage.username().sendKeys(userName);
        Log.info("在QQ郵箱登錄頁面的密碼輸入框中輸入 "+passWord);
        loginPage.password().sendKeys(passWord);
        Log.info("單擊登錄頁面的登錄按鈕");
        loginPage.login_button().click();
        //Thread.sleep(5000);
    }
}

 

AddContactAction.java

package appmodules;

import org.openqa.selenium.WebDriver;
import pageobject.AddressBookPage;
import pageobject.HomePage;
import until.Log;

public class AddContactAction {
    
    public static void execute(
            WebDriver driver,
            String userName,
            String passWord,
            String contactName,
            String contactEmail,
            String contactCountry,
            String contactProvince,
            String contactCity) throws Exception{
        //調用登錄方法
        Log.info("調用LoginAction類的execute方法");
        LoginAction.execute(driver, userName, passWord);
        Thread.sleep(3000);
        
        HomePage homePage = new HomePage(driver);
        Log.info("登錄后,單擊通訊錄鏈接");
        homePage.addressLink().click();
        driver.switchTo().frame("mainFrame");
        
        AddressBookPage addressBookPage = new AddressBookPage(driver);
        Log.info("休眠3秒,等待打開通訊錄頁面");
        Thread.sleep(3000);
        
        Log.info("在通訊錄頁面,單擊'新增聯系人'按鈕");
        addressBookPage.addContactButton().click();
        
        Log.info("在聯系人姓名輸入框中,輸入: "+contactName);
        addressBookPage.addContactName().sendKeys(contactName);
        Log.info("在聯系人郵箱輸入框中,輸入: "+contactEmail);
        addressBookPage.addContactEmail().sendKeys(contactEmail);
        //addressBookPage.addContactTell().sendKeys(contactTell);
        Log.info("在聯系人國家輸入框中,輸入: "+contactCountry);
        addressBookPage.addContactCounty().sendKeys(contactCountry);
        Log.info("在聯系人省份輸入框中,輸入: "+contactProvince);
        addressBookPage.addContactProvince().sendKeys(contactProvince);
        Log.info("在聯系人城市輸入框中,輸入: "+contactCity);
        addressBookPage.addContactCity().sendKeys(contactCity);
        Log.info("單擊確定按鈕");
        addressBookPage.addContactSaveButton().click();
        Log.info("休眠5秒,等待保存聯系人后返回通訊錄的主頁面");
        Thread.sleep(5000);
    }
}

TestQQEmailAddContact.java

package testscript;

import java.io.IOException;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.Assert;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.DataProvider;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;

import appmodules.AddContactAction;
import until.Constant;
import until.ExcelUntil;
import until.Log;

public class TestQQEmailAddContact {
    
    public WebDriver driver;
    //調用Constant類中的常量url
    private String url = Constant.URL;
    
    @DataProvider(name="testData")
    public static Object[][] data() throws IOException{
        //調用ExcelUntil工具類中getTestData()方法獲取測試數據
        return ExcelUntil.getTestData(Constant.TestDataExcelFilePath, Constant.TestDataExcelFileSheet);
    }
    
    //使用名稱為testData的dataProvider作為測試方法的測試數據集
    //測試方法一共有12個參數,分別對應Excel數據文件中的1~12列
    @Test(dataProvider="testData")
    public void testAddressBook(
            String caseRowNumber,
            String testCaseName,
            String userName,
            String passWord,
            String contactName,
            String contactEmail,
            String contactTell,
            String contactCountry,
            String contactProvince,
            String contactCity,
            String assertContactName,
            String assertContactEmail
            ) throws Exception{
        Log.startTestCase(testCaseName);
        driver.get(url);
        
        Log.info("調用AddContactAction類的execute方法");
        try {
            AddContactAction.execute(driver, userName, passWord, contactName, contactEmail, contactCountry, contactProvince, contactCity);
        } catch (AssertionError error) {
            Log.info("添加聯系人失敗");
            //設置Excel中測試數據行的執行結果為“測試執行失敗”
            ExcelUntil.setCellData(Integer.parseInt(caseRowNumber.split("[.]")[0]), ExcelUntil.getLastColumnNum(), "測試執行失敗");
            Assert.fail("執行AddContactAction類的execute方法失敗");
        }
        Log.info("調用AddContactAction類的execute方法后,休眠3秒鍾");
        Thread.sleep(3000);
        
        Log.info("斷言通訊錄頁面是否包含聯系人姓名關鍵字");
        try {
            Assert.assertTrue(driver.getPageSource().contains(assertContactName));
        } catch (AssertionError error) {
            Log.info("斷言通訊錄頁面是否包含聯系人姓名的關鍵字失敗");
            ExcelUntil.setCellData(Integer.parseInt(caseRowNumber.split("[.]")[0]), ExcelUntil.getLastColumnNum(), "測試執行失敗");
            Assert.fail("斷言通訊錄頁面是否包含聯系人姓名的關鍵字失敗");
        }
        
        Log.info("斷言通訊錄頁面是否包含聯系人郵箱關鍵字");
        try {
            Assert.assertTrue(driver.getPageSource().contains(assertContactEmail));
        } catch (AssertionError error) {
            Log.info("斷言通訊錄頁面是否包含聯系人郵箱的關鍵字失敗");
            ExcelUntil.setCellData(Integer.parseInt(caseRowNumber.split("[.]")[0]), ExcelUntil.getLastColumnNum(), "測試執行失敗");
            Assert.fail("斷言通訊錄頁面是否包含聯系人郵箱的關鍵字失敗");
        }
        
        Log.info("新建聯系人全部斷言成功,在Excel的測試數據文件的'測試執行結果'中寫入'測試執行成功'");
        //斷言全部成功,在Excel的測試數據文件的“測試執行結果”中寫入“測試執行成功”
        ExcelUntil.setCellData(Integer.parseInt(caseRowNumber.split("[.]")[0]), ExcelUntil.getLastColumnNum(), "測試執行成功");
        Log.info("測試結果成功寫入excel數據文件中的測試執行結果列");
        Log.endTestCase(testCaseName);

    }
    
    @BeforeMethod
    public void beforeMethod(){
        System.setProperty("webdriver.chrome.driver", "e:\\chromedriver.exe");
        driver = new ChromeDriver();
    }
    
    @AfterMethod
    public void afterMethod(){
        driver.quit();
    }

    @BeforeClass
    public void BeforeClass() throws Exception{
        ExcelUntil.setExcelFile(Constant.TestDataExcelFilePath,Constant.TestDataExcelFileSheet);
    }
}

 

ObjectMap.properties

 

QQ郵箱的測試數據.xlsx

 

個人微信訂閱號:專注測試開發、自動化測試。

 


免責聲明!

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



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