Selenium 框架:数据、关键词和混合驱动

什么是 Selenium 框架?

这个 Selenium 自动化框架 是一种使代码维护变得简单高效的代码结构。如果没有框架,用户可能会将“代码”和“数据”放在同一个位置,既不可重用也不可读。框架可以带来有益的结果,例如提高代码的可重用性、更高的可移植性、降低脚本维护成本、提高代码的可读性等。

有哪些 Selenium 骨架

主要有三种 框架类型 由...制作 Selenium WebDriver 自动化手动测试用例

  • 数据驱动框架
  • 关键字驱动框架
  • 混合驱动框架

有哪些 Selenium 骨架

数据驱动框架 Selenium

数据驱动框架 Selenium 是一种将数据集与测试用例分离的方法。一旦将数据集与测试用例分离,就可以轻松修改它以实现特定功能,而无需更改代码。它用于从外部文件获取测试用例和套件,例如 Excel、.csv、.xml 或一些数据库表。

数据驱动框架 Selenium

为了读取或写入 Excel,Apache 提供了一个非常著名的库 POI。该库足以读取和写入 XLS XLSX Excel 文件格式。

读书 XLS 文件, 高速SF 实现由 POI 库提供。

读书 XLSX, 跨系统安全框架 实施 POI 图书馆 将是选择。让我们详细研究一下这些实现。

我们已经在 先前的教程

关键字驱动框架 Selenium

关键字驱动框架 Selenium 是一种通过分离常用功能和指令集的关键字来加速自动化测试的方法。所有要执行的操作和指令都写在某个外部文件(如 Excel 表)中。用户可以轻松控制和指定他们想要测试的功能。

完整框架如下

关键字驱动框架 Selenium

如你所见,这是一个 5 步框架。让我们逐步详细研究它

步骤1)

  • 驱动脚本 Execute.java 将调用 ReadGuru99ExcelFile.java
  • ReadGuru99ExcelFile.java 有 POI 脚本,用于从 Excel 读取数据

步骤2)

  • ReadGuru99ExcelFile.java 将从 TestCase.xlsx 读取数据
  • 该表格如下所示:

关键字驱动框架 Selenium

  • 框架会根据Excel文件中写入的关键字,执行UI上的操作。
  • 例如,我们需要单击按钮“登录”。相应地,我们的 Excel 将有一个关键字“单击”。现在 AUT 可以在一个页面上有数百个按钮,为了识别登录按钮,我们将在 Excel 中输入对象名称作为 loginButton 和对象类型作为名称(参见上图中突出显示的行)。对象类型可以是 Xpath、名称 CSS 或任何其他值

步骤3) ReadGuru99ExcelFile.java 将把这些数据传递给驱动脚本 Execute.java

步骤4)

  • 对于我们所有的 UI Web 元素,我们需要创建一个对象存储库,我们将在其中放置它们的元素定位器(如 Xpath、名称、CSS 路径、类名等)。

关键字驱动框架 Selenium

  • Execute.java(我们的驱动脚本)将读取整个对象存储库并将其存储在变量中
  • 要读取这个对象存储库,我们需要一个具有 getObjectRepository 方法来读取它的 ReadObject 类。
  • 关键字驱动框架 Selenium

注意: 您可能会想为什么我们需要创建对象存储库。答案有助于代码维护。例如,我们在 10 个不同的测试用例中使用名称为 btnlogin 的按钮。将来,开发人员决定将名称从 btnlogin 更改为提交。您必须在所有 10 个测试用例中进行更改。对于对象存储库,您只需在存储库中进行一次更改。

步骤5)

  • 驱动程序将把 Excel 和对象存储库中的数据传递到 UIOpera类
  • UIOperation 类具有执行与 excel 中提到的关键字(如 CLICK、SETTEXT 等)相对应的操作的函数
  • UIOperation类是一个 Java 具有对 Web 元素执行操作的代码实际实现的类

关键字驱动框架 Selenium

完整的项目将如下所示:

关键字驱动框架 Selenium

我们来看一个例子:

测试场景: 我们正在执行 2 个测试用例

对象.属性

url=https://demo.guru99.com/V4/
username=uid
password=password
title=barone
loginButton=btnLogin
resetButton=btnReset

ReadGuru99Excel文件.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;    
    }
}

读取对象.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;
    }
    
}

UIOpera函数

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

执行测试.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");
            }
        }
    }
}

执行后,输出如下 -

关键字驱动框架 Selenium

下载 Selenium 本教程中演示的项目文件

混合驱动框架

混合驱动框架 in Selenium 是我们利用关键字驱动框架和数据驱动框架的优势的概念。这是一个易于使用的框架,允许手动测试人员仅通过查看关键字、测试数据和对象存储库来创建测试用例,而无需在框架中编码。

这里对于关键字,我们将使用Excel文件来维护测试用例,对于测试数据,我们可以使用数据提供者 测试 框架。

混合驱动框架

在我们的混合框架中,我们不需要在关键字驱动框架中改变任何东西,这里我们只需要用 HybridExecuteTest.java 文件替换 ExecuteTest.java 文件。

混合驱动框架

这个 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;    
    }
}

结语

  • 我们可以使用以下方法创建三种类型的测试框架 Selenium WebDriver。
  • A Selenium 自动化框架可分为数据驱动、关键字驱动和混合框架。
  • 我们可以使用以下方法实现数据驱动框架 TestNG的数据提供商。
  • 在关键字驱动框架中,关键字被写在一些外部文件(如excel文件)中,java代码将调用此文件并执行测试用例。
  • 混合框架是关键字驱动框架和数据驱动框架的混合。

下载 Selenium 本教程中演示的项目文件