Selenium WebDriver 數據驅動測試框架

Selenium WebDriver 數據驅動測試框架,以QQ郵箱添加聯繫人爲示例,測試框架結構以下圖,詳細內容請閱讀吳曉華編著《Selenium WebDiver 實戰寶典》:css

ObjectMap.javajava

/**
 * 使用配置文件存儲測試頁面上的定位和定位表達式,作到定位數據和程序的分離
 */
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.javaweb

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.javachrome

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.javaapache

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.javaapp

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.javaxss

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.javaide

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

相關文章
相關標籤/搜索