Selenium 简明教程
Selenium - Data Driven Framework
Selenium Webdriver 可用于开发基于数据驱动框架的测试脚本。数据驱动框架主要用于创建依赖于外部源中可用数据的测试用例。此外部源可以是拥有 .txt、.properties、.xlsx、.xls、.csv 扩展名的任何文件,还可以在数据提供程序的帮助下。
Selenium Webdriver can be used to develop test scripts which are based on the data driven framework. A data driven framework is mostly used to create test cases which are dependent on data available from an external source. This external source can be any file having extensions with .txt, .properties, .xlsx, .xls, .csv, and also with the help of data providers.
数据驱动框架是一种测试用例与数据集分离的框架。此外,它提供了针对多组数据运行相同测试用例的规定。由于测试代码实现和测试数据彼此独立,因此可以修改数据集而不影响实现逻辑,反之亦然。
A data driven framework is the one in which the test cases are segregated from the data set. Also, it gives the provision to run the same test case against multiple sets of data. Since the test code implementation and test data are independent of each other, the data set can be modified without impacting the implementation logic and vice-versa.
Why Data Driven Testing Framework is Used?
在数据驱动测试框架中,针对同一测试用例可以运行多组数据,因此可以针对广泛的数据范围测试相同的应用程序,而无需额外的代码。因此,代码一旦开发好,就可以多次使用。
In a data driven testing framework, more than one set of data can be run against the same test case, thus the same application can be tested against a wide data range without requiring additional code. Thus code is developed once but reused multiple times.
数据驱动测试框架允许多次执行测试用例,而无需增加测试用例的数量。有时,测试数据会自动生成,这允许针对广泛的随机数据集对应用程序进行测试。在这种情况下,数据驱动测试框架可确保更健壮和高质量的产品。
A data driven testing framework allows multiple execution of test cases without increasing the number of test cases. Sometimes, test data is generated automatically and this allows the application to be tested against a wide range of random data sets. In such a scenario, a data driven testing framework ensures a more robust and quality product.
Advantages of Data Driven Testing Framework
数据驱动测试框架通过确保更结构化的执行,从而允许对测试用例进行优化利用。这也有助于缩短测试周期,同时确保产品质量。包含各种函数、方法和动作的测试实现代码在数据驱动测试框架中使用广泛的数据集进行测试。
A data driven testing framework allows optimal use of test cases by ensuring a more structured execution. This also helps to shorten the test cycle while ensuring a quality product. The test implementation code comprising various functions, methods, and actions are tested with a wide range of data sets in a data driven testing framework.
Differences Between Data Driven and Keyword Driven Testing Framework
数据驱动框架和关键字驱动框架之间存在一些差异。关键字驱动框架更容易维护,因为测试数据、关键字和实现逻辑层之间仍然有更多抽象,而数据驱动框架比关键字驱动框架更难维护,因为抽象仅存在于测试数据和测试脚本之间。
There exists some differences between the data driven and keyword driven frameworks. A keyword driven framework is easier to maintain since more abstractions remain among the test data, keywords, and implementation logic layers, while a data driven framework is more difficult to maintain than a keyword driven framework as abstraction exists only between the test data and test scripts.
与数据驱动框架相比,关键字驱动框架需要更系统的规划,因为在数据驱动框架中,我们只将测试数据与测试脚本分开。
More systemic planning is required to be in place for a keyword driven framework rather than in a data driven framework since in the data driven framework we are only segregating the test data from the test scripts.
Example 1 - Data Driven with Excel
让我们举一个示例,其中我们将使用 Apache POI 库通过 Excel 执行数据驱动测试。让我们以名为 DetailsStudent.xlsx 文件的以下 Excel 为例,我们将从该 Excel 文件中读取值并将这些数据输入到下面的注册页面中,一旦成功完成,我们将在单元格(在同一行和 E 列中)中写下文本 - Test Case: Pass 。如果不成功,我们将在同一单元格中写下文本 - Test Case: Fail 。
Let us take an example where we would perform data driven testing with excel using the Apache POI library. Let us take an example of the below excel named the DetailsStudent.xlsx file, where we would read the value from that excel file and input those data to the below registration page and once successfully done, we would write the text - Test Case: Pass in the cell(at same row and Column E). If not successfully done, we would write the text - Test Case: Fail in that same cell.

下图显示了注册页面,我们将在字段 Full Name:, Last Name:, Username: 和 Password 中输入来自 DetailsStudent.xlsx 文件的数据。
The below image shows the registration page where we would enter data in the fields Full Name:, Last Name:, Username:, and Password from the DetailsStudent.xlsx file.

Please Note − DetailsStudent.xlsx Excel 文件已放在 Resources 文件夹下方的项目中,如下图所示。
Please Note − The DetailsStudent.xlsx excel file was placed within the project under the Resources folder as shown in the below image.

How to Install the Apache POI?
Step 1 - 从以下链接中添加 Apache POI 通用依赖项 −
Step 1 − Add Apache POI Common dependencies from the below link −
Step 2 - 从以下链接中添加基于 OPC 和 OOXML 架构的 Apache POI API 依赖项 −
Step 2 − Add Apache POI API Based On OPC and OOXML Schemas dependencies from the below link −
Step 3 - 使用所有依赖项保存 pom.xml 并更新 Maven 项目。
Step 3 − Save the pom.xml with all the dependencies and update the maven project.
ExcelReadWrite.java 中的代码实现
Code Implementation in ExcelReadWrite.java
package org.example;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
public class ExcelReadWrite {
public static void main(String args[]) throws IOException {
// identify location of .xlsx file
File f = new File("./Resources/DetailsStudent.xlsx");
FileInputStream i = new FileInputStream(f);
// instance of XSSFWorkbook
XSSFWorkbook w = new XSSFWorkbook(i);
// create sheet in XSSFWorkbook with name Details1
XSSFSheet s = w .getSheet("Details1");
// handle total rows in XSSFSheet
int r = s.getLastRowNum() - s.getFirstRowNum();
// Initiate the Webdriver
WebDriver driver = new ChromeDriver();
// adding implicit wait of 15 secs
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
// Opening the webpage where we will identify elements
driver.get("https://www.tutorialspoint.com/selenium/practice/register.php#");
//Identify elements for registration
WebElement fname = driver.findElement(By.xpath("//*[@id='firstname']"));
WebElement lname = driver.findElement(By.xpath("//*[@id='lastname']"));
WebElement uname = driver.findElement(By.xpath("//*[@id='username']"));
WebElement pass = driver.findElement(By.xpath("//*[@id='password']"));
WebElement btn = driver.findElement(By.xpath("//*[@id='signupForm']/div[5]/input"));
// loop through rows, read and enter values in form
for(int j = 1; j <= r; j++) {
fname.sendKeys(s.getRow(j).getCell(0).getStringCellValue());
lname.sendKeys(s.getRow(j).getCell(1).getStringCellValue());
uname.sendKeys(s.getRow(j).getCell(2).getStringCellValue());
pass.sendKeys(s.getRow(j).getCell(3).getStringCellValue());
// submit registration form
btn.click();
// verify form submitted
WebElement fname1 = driver.findElement(By.xpath("//*[@id='firstname']"));
String value = fname1.getAttribute("value");
// create cell at Column 4 to write values in excel
XSSFCell c = s.getRow(j).createCell(4);
// write results in excel
if (value.isEmpty()) {
c.setCellValue("Test Case: PASS");
} else {
c.setCellValue("Test Case: FAIL");
}
// complete writing value in excel
FileOutputStream o = new FileOutputStream("./Resources/DetailsStudent.xlsx");
w.write(o);
}
// closing workbook object
w.close();
// Quitting browser
driver.quit();
}
}
添加到 pom.xml 的依赖关系。
Dependencies added to pom.xml.
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>SeleniumJava</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>16</maven.compiler.source>
<maven.compiler.target>16</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<!-- https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java -->
<dependencies>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>4.11.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.poi/poi -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>5.2.5</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>5.2.5</version>
</dependency>
</dependencies>
</project>
Output
Process finished with exit code 0
在上面的示例中,我们已经读取了整个 Excel 文件,并在第五列的单元格中写入了值 Test Case: Pass 。
In the above example, we had read the whole excel file and had written the value Test Case: Pass in the cell at the fifth Column.
最后,收到了消息 Process finished with exit code 0 ,表示代码成功执行。
Finally, the message Process finished with exit code 0 was received, signifying successful execution of the code.

如上图所示,在测试基于同一 Excel 中注册数据后, Test Case: Pass 被写入 DetailsStudent.xlsx Excel 文件的第 5 列中。
As seen in the image above, Test Case: Pass was written into DetailsStudent.xlsx excel file in the Column 5 post the test run with respect to the registration data available in the same excel.
Example 2 - Data Driven with TestNG DataProvider
我们举一个示例,在其中我们将借助称为 DataProvider 的 TestNG 的默认功能执行数据驱动测试。DataProvider 用于向任何测试方法提供数据。
Let us take an example where we would perform data driven testing with the help of the default functionality of TestNG which is known as the DataProvider. The DataProvider is used to feed data to any test method.
我们将使用 TestNG DataProvider 在与前面示例中提到的相同的注册页面中输入值,我们在该页面中使用字段 Full Name:, Last Name:, Username: 和 Password 输入数据。
We would input values in the same registration page as mentioned in the previous example where we would enter data in the fields Full Name:, Last Name:, Username:, and Password using the TestNG DataProvider.
How to Install the TestNG?
-
Install Java(version above 8) in the system and check if it is present with the command: java -version. The java version installed will be visible if installation has been completed successfully.
-
Install maven in the system and check if it is present with the command: mvn -version. The maven version installed will be visible if installation has been completed successfully.
-
Install any IDE like Eclipse, IntelliJ, and so on.
-
Add the TestNG dependencies from the link below: https://mvnrepository.com/artifact/org.testng/testng.
DataTest.java 中的代码实现
Code Implementation in DataTest.java
package CrossBrw;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.annotations.*;
import java.util.concurrent.TimeUnit;
public class DataTest {
WebDriver driver;
@BeforeTest
public void setup() throws Exception {
// Initiate the Webdriver
driver = new ChromeDriver();
// adding implicit wait of 12 secs
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
// Opening the webpage
driver.get("https://www.tutorialspoint.com/selenium/practice/register.php#");
}
@Test(dataProvider = "registration-data")
public void userRegistration
(String fname1, String lname1, String uname1, String pass1) {
//Identify elements for registration
WebElement fname = driver.findElement(By.xpath("//*[@id='firstname']"));
WebElement lname = driver.findElement(By.xpath("//*[@id='lastname']"));
WebElement uname = driver.findElement(By.xpath("//*[@id='username']"));
WebElement pass = driver.findElement(By.xpath("//*[@id='password']"));
// enter details from data provider
fname.sendKeys(fname1);
lname.sendKeys(lname1);
uname.sendKeys(uname1);
pass.sendKeys(pass1);
// get values entered
String text = fname.getAttribute("value");
String text1 = lname.getAttribute("value");
String text2 = uname.getAttribute("value");
String text3 = pass.getAttribute("value");
System.out.println("Entered first name: " + text);
System.out.println("Entered last name: " + text1);
System.out.println("Entered username: " + text2);
System.out.println("Entered password: " + text3);
}
@DataProvider (name = "registration-data")
public Object[][] registrationData(){
return new Object[][]
{ {"Ram", "Ganesh", "ABC", "Password12"} };
}
@AfterTest
public void teardown() {
// quitting browser
driver.quit();
}
}
添加到 pom.xml 的依赖关系。
Dependencies added to pom.xml.
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>SeleniumJava</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>16</maven.compiler.source>
<maven.compiler.target>16</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<!-- https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java -->
<dependencies>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>4.11.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.testng/testng -->
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>7.9.0</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
Output
Entered first name: Ram
Entered last name: Ganesh
Entered username: ABC
Entered password: Password12
===============================================
Default Suite
Total tests run: 1, Passes: 1, Failures: 0, Skips: 0
===============================================
Process finished with exit code 0
在上面的示例中,我们已经从 DataProvider 中可用的数据输入了注册页面中的数据,并使用消息获取了输入的值,消息在控制台为 Entered first name: Ram, Entered last name: Ganesh, Entered username: ABC 和 Entered password: Password12 。
In the above example, we had input the data in the registration page from the data available in the DataProvider and obtained the values entered with the message in the console - Entered first name: Ram, Entered last name: Ganesh, Entered username: ABC, and Entered password: Password12.
控制台中为 Total tests run: 1 的结果,因为有一个方法 = 使用 @Test 注释 - userRegisterration()。
The result in the console shows Total tests run: 1, as there is one method= with @Test annotation - userRegisterration().
最后,收到消息 Passes: 1 和 Process finished with exit code 0 ,表示代码成功执行。
Finally, the message Passes: 1, and Process finished with exit code 0 was received, signifying successful execution of the code.
这就总结了我们对 Selenium Webdriver - 数据驱动框架的全面介绍。我们已经从描述什么是数据驱动框架、为什么要使用数据驱动框架、数据驱动框架的优点、数据驱动框架和关键字驱动框架之间的差异开始,并通过使用 Excel 和 TestNG 中的 DataProvider 在 Selenium Webdriver 中实现数据驱动框架的示例来完成。
This concludes our comprehensive take on the tutorial on Selenium Webdriver - Data Driven Framework. We’ve started with describing what is a data driven framework, why is a data driven framework used, what are the advantages of a data driven framework, what are the differences between data driven and keyword driven frameworks, and walked through examples of how to implement a data driven framework using excel and dataProvider in TestNG along with Selenium Webdriver.
这使你具备了 Selenium Webdriver 中数据驱动框架的深入知识。明智的做法是不断实践你学到的知识,并探索与 Selenium 相关的其他内容,以加深理解并拓展视野。
This equips you with in-depth knowledge of the Data Driven Framework in Selenium Webdriver. It is wise to keep practicing what you’ve learned and exploring others relevant to Selenium to deepen your understanding and expand your horizons.