• 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 + "	 获取的定位表达式:" + 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

    个人微信订阅号:专注测试开发、自动化测试。

  • 相关阅读:
    python3.6配置flask
    jquery匿名函数和闭包(它山之石)笔记
    .net扩展方法
    对象继承
    MAC OS X PKG FILES
    NLP——天池新闻文本分类 Task2
    Python基础TASK1:变量与数据类型
    NLP——天池新闻文本分类 Task1
    随机分析与随机过程中的一些基本概念
    Java线程池
  • 原文地址:https://www.cnblogs.com/wakey/p/10893993.html
Copyright © 2020-2023  润新知