在上一篇中介绍了 Selenium使用TestNG的@DataProvider注解实现参数化测试的方法,这种方式的参数化在数据量比较大的情况下不太方便维护。在数据量比较大的情况下我们可以把数据存放在Excel表格中,借助Apache的POI工具从Excel中读取参数化的数据。
Apache POI简介:
Apache POI是一个开源的java包,主要用来处理各种格式的微软Office系列文档。使用POI我们可以创建、修改、读取以下格式的文件
- DOC – 97-2003 word document
- DOCX – 2007/2010/2013 word document
- PPT – 97-2003 powerpoint presentation
- PPTX – 2007/2010/2013 powerpoint presentation
- XLS – 97-2003 excel spreadsheet
- XLSX – 2007/2010/2013 excel spreadsheet
POI与JXL比较:
- 从Excel读数据也可以通过JXL jar包,但是它只支持旧的97~2003的Excel版本,不支持新的Excel版本。
- POI支持xls和xlsx的版本。
- JXL的开发已经停止了,最近一次更新是在2011年。
- POI还在维护中,POI最新的版本是2017年9月的3.17的版本。
本文介绍Selenium Java框架中使用Selenium+TestNG+Maven+Apache POI实现从Excel中读取参数化数据的方法,参数化在selenium中其实有点复杂,所以有人说“ Selenium Webdriver is more an automated testing framework than a ready-to-use tool” Selenium更偏向于是一个测试框架而不是一个ready-to-use的工具。
所需环境:
- Eclipse IDE
- TestNG
- Maven
- Firefox browser
- Selenium Webdriver
- Apache POI
前置准备:
1. 使用Maven的POM文件下载Apache POI
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.17</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.17</version>
</dependency>
再一次感叹Selenium Java框架中的Maven在找需要的工具jar包时简直不要太方便!
引入后我们在脚本中一般需要用到以下POI的包
import org.apache.poi.ss.usermodel.CellType;
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;
2. 准备存放参数化数据的Excel文件 xlsx
注:Excel文件中的这些数据要选中,在单元格格式设置中要设置成Text格式,保存并关闭掉Excel文件。
具体步骤:
1. 定义一个方法,借助POI从Excel读取数据
从Excel读取数据的getExcelData方法实现是本例中最关键的部分
@DataProvider(name = "provideUser")
public Object[][] provideData() throws IOException{
Object[][] arrayObject = getExcelData("D:\\testdata.xlsx","Sheet1");
return arrayObject;
}
//下面的方法实现从Excel中获取数据
public String[][] getExcelData(String fileName,String sheetName) throws IOException{
String[][] excelData = null;
//实现从磁盘读取文件
FileInputStream fs = new FileInputStream(fileName);
//使用POI接受文件流读取的Excel整体文件
XSSFWorkbook wb = new XSSFWorkbook(fs);
//POI读取Excel的sheet页
XSSFSheet sh = wb.getSheet(sheetName);
//获取总行数
int totalNoOfRows = sh.getLastRowNum();
//获取总列数
int totalNoOfCols = sh.getRow(0).getLastCellNum();
//创建String类型的二维数组“excelData” ,指定数组的行和列用来接收从Excel读取出的数据
excelData = new String[totalNoOfRows][totalNoOfCols];
//使用for循环从Excel单元格取数据,为上面的二维数组excelData进行赋值
for (int i=1; i<=totalNoOfRows;i++) {
XSSFRow row = sh.getRow(i);
for (int j=0;j<totalNoOfCols;j++) {
XSSFCell cell = row.getCell(j);
if(cell.getCellTypeEnum() == CellType.STRING) {
excelData[i-1][j] = cell.getStringCellValue();
System.out.println("String类型" + excelData[i-1][j]);
}else {
excelData[i-1][j] = String.valueOf(cell.getNumericCellValue());
}
}
}
return excelData;
}
注:上面for循环中i代表行,j代表列,实现的基本思路是先取出行的数据(i从1开始是没取第一行的标题数据),然后再取出这一行每列的数据,赋值给excelData这个String类型的二维数组。if...else是处理如果取出的值不是String类型的要做下转换。
2. 定义需要进行参数化测试的@Test方法,并指定用来获取数据的DataProvider名称
下面是使用错误的用户名密码进行CSDN登录的测试方法
@Test(dataProvider = "provideUser")
public void openWebSite(String username, String password) throws InterruptedException {
//输入用户名
driver.findElement(By.id("username")).click();
driver.findElement(By.id("username")).clear();
driver.findElement(By.id("username")).sendKeys(username);
//输入密码
driver.findElement(By.id("password")).click();
driver.findElement(By.id("password")).clear();
driver.findElement(By.id("password")).sendKeys(password);
//点击登录按钮
driver.findElement(By.xpath("//input[@class='logging']")).click();
//Thread.sleep(3000);
String errormessage = driver.findElement(By.id("error-message")).getText();
Assert.assertEquals(errormessage,"长时间未修改密码,请修改密码后登录" );
}
【完成】
下面是完整的代码:
package com.yoyotesting.selenium3maven;
import org.testng.annotations.Test;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.DataProvider;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.testng.Assert;
import org.testng.annotations.AfterClass;
import org.apache.poi.ss.usermodel.CellType;
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 OpenWebsiteTestNGCSDNPOI {
public WebDriver driver;
@BeforeClass
public void setUp() throws InterruptedException {
//定义gecko driver的获取地址
System.setProperty("webdriver.gecko.driver", "D:\\BrowserDriver\\geckodriver.exe");
//创建一个叫driver的对象,启动火狐浏览器
driver = new FirefoxDriver();
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
//通过对象driver调用具体的get方法来打开网页
driver.get("https://www.csdn.net/");
//最大化浏览器窗口
driver.manage().window().maximize();
Thread.sleep(3000);
//点击登录按钮
driver.findElement(By.linkText("登录")).click();
//点击账号登录
driver.findElement(By.linkText("账号登录")).click();
}
@DataProvider(name = "provideUser")
public Object[][] provideData() throws IOException{
Object[][] arrayObject = getExcelData("D:\\testdata.xlsx","Sheet1");
return arrayObject;
}
//下面的方法实现从Excel中获取数据
public String[][] getExcelData(String fileName,String sheetName) throws IOException{
String[][] excelData = null;
//实现从磁盘读取文件
FileInputStream fs = new FileInputStream(fileName);
//使用POI接受文件流读取的Excel整体文件
XSSFWorkbook wb = new XSSFWorkbook(fs);
//POI读取Excel的sheet页
XSSFSheet sh = wb.getSheet(sheetName);
//获取总行数
int totalNoOfRows = sh.getLastRowNum();
//获取总列数
int totalNoOfCols = sh.getRow(0).getLastCellNum();
//创建String类型的二维数组“excelData” ,指定数组的行和列用来接收从Excel读取出的数据
excelData = new String[totalNoOfRows][totalNoOfCols];
//使用for循环从Excel单元格取数据,为上面的二维数组excelData进行赋值
for (int i=1; i<=totalNoOfRows;i++) {
XSSFRow row = sh.getRow(i);
for (int j=0;j<totalNoOfCols;j++) {
XSSFCell cell = row.getCell(j);
if(cell.getCellTypeEnum() == CellType.STRING) {
excelData[i-1][j] = cell.getStringCellValue();
System.out.println("String类型" + excelData[i-1][j]);
}else {
excelData[i-1][j] = String.valueOf(cell.getNumericCellValue());
}
}
}
return excelData;
}
@Test(dataProvider = "provideUser")
public void openWebSite(String username, String password) throws InterruptedException {
//输入用户名
driver.findElement(By.id("username")).click();
driver.findElement(By.id("username")).clear();
driver.findElement(By.id("username")).sendKeys(username);
//输入密码
driver.findElement(By.id("password")).click();
driver.findElement(By.id("password")).clear();
driver.findElement(By.id("password")).sendKeys(password);
//点击登录按钮
driver.findElement(By.xpath("//input[@class='logging']")).click();
//Thread.sleep(3000);
String errormessage = driver.findElement(By.id("error-message")).getText();
Assert.assertEquals(errormessage,"长时间未修改密码,请修改密码后登录" );
}
@AfterClass
public void tearDown() {
//退出浏览器
driver.quit();
}
}
****************************************************************************************************
最近我会持续更新Selenium Java的相关文章,也请大家多多关注我的视频课程
全网最新、最完整、最具性价比的自动化测试课程
Selenium3 Java自动化测试完整教程
*****************************************************************************************************