Selenium——数据驱动测试浅析
什么是数据驱动测试
- 相同的测试脚本使用不同的测试数据来执行,
测试数据和测试行为进行了完全的分离
。这样的测试脚本设计模式称为数据驱动。 - 行为驱动方式:Cucumber;
数据驱动方式:真实的场景,广义上的参数化
关键字驱动模式:定位方式放在外部文件(如excel、属性文件中)
页面对象模式:PO模式,一个页面对应一个类
混合模式,根据实际情况混用。 - 使用数据驱动测试的步骤:
1)编写测试脚本
,脚本需要支持程序对象、文件或数据库读入测试数据
2)将测试脚本使用的测试数据存入
程序对象、文件或数据库等外部介质
中
3)运行脚本,循环调用
存储在外部介质的测试数据。
4)验证
所有的测试结果是否都符合期望结果。 - 实现数据驱动的四种方式:
(1)数组
(2)txt/csv(I/O读取数据,转换为Object[][]
)
(3)excel(apache poi读取Excel数据,转换为Object[][]
)
(4)数据库(JDBC读取数据库数据,转换为Object[][]
)
使用TestNG进行数据驱动
-
环境准备:创建一个新的java project,下载poi的包后,加载到eclipse中、导入selenium、TestNG。如下图所示:
-
数组形式,举例
package xxx.xhx.www;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
public class ArrayDataProvider {
//应用这个数据提供者提供的数据
//@Test(dataProvider="data1")
@Test(dataProvider="data1",dataProviderClass=NSDataProvider.class)
public void test1(String username, String password, String url) {
System.out.println(username + "---" + password);
}
}
package xxx.xhx.www;
import org.testng.annotations.DataProvider;
public class NSDataProvider {
//写数据提供者
@DataProvider(name="data1")
public Object[][] getData(){
return new Object[][] {
{"tom1", "111", "url1"},
{"tom2", "222", "url2"}
};
}
@DataProvider(name="data2")
public Object[][] getData2(){
return new Object[][] {
{"ami1", "111", "url1"},
{"ami2", "222", "url2"}
};
}
}
控制台输出:
-
txt:
在当先包下,创建一个名为data的文件夹,其中新建一个txt文件,内容如下所示:
两个类分别如下:
注意第一个类提取数据的流的操作。
package xxx.xhx.www;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
/**
* 把txt数据读取出来,转换为二维数组
*/
public class TxtDataProvider {
//在本类中简单写一下,看是否转换正确。
// @Test(dataProvider = "data1")
// public void test1(String a, String b) {
// System.out.println(a + "----" + b);
// }
@DataProvider(name="data1")
public Object[][] getData1() throws IOException{
return new TxtDataProvider().getDataByTxt("data/user.txt");
}
public Object[][] getDataByTxt(String fileName) throws IOException {
File file = new File(fileName);
Object[][] data = null;
FileInputStream input = new FileInputStream(file);
InputStreamReader isReader = new InputStreamReader(input); //把字节流转化为字符流
BufferedReader bReader = new BufferedReader(isReader);
String record = bReader.readLine(); // 作用把表头略去
// 读取一行,分割为字符数组。把字符数组保存在List
List<String[]> dataList = new ArrayList<String[]>();
while ((record = bReader.readLine()) != null) {// 从第二行数据开始读的
String[] fields = record.split("\t"); //数据间如果以,分割,这里的\t换成,
dataList.add(fields);
}
bReader.close();
isReader.close();
input.close();
// 把List转换为Object[][]
data = new Object[dataList.size()][];
for (int i = 0; i < dataList.size(); i++) {
data[i] = dataList.get(i);
}
return data;
}
}
package xxx.xhx.www;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
public class ArrayDataProvider {
//应用这个数据提供者提供的数据
//@Test(dataProvider="data1")
@Test(dataProvider="data1",dataProviderClass=TxtDataProvider.class)
public void test1(String username, String password) {
System.out.println(username + "---" + password);
}
}
效果:
在此留下一个相关操作的参考网页,比本篇更为具体
链接
- excel
首先打开当前包所在的位置,如下图所示:
点击图中的链接后,找到data文件夹,右键创建一个excel。
注意:当想存的字符串仅由数字构成时,可以在其前加一个英文的单引号 '
,这样就会认为是一个字符串类型的了。
如下图所示:
package xxx.xhx.www;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
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.XSSFWorkbook;
import org.omg.PortableInterceptor.USER_EXCEPTION;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import graphql.language.Field;
import graphql.parser.antlr.GraphqlParser.FieldsDefinitionContext;
public class ExcelDataProvider {
@Test(dataProvider = "excel")
public void test1(String a, String b) {
System.out.println(a + "----->" + b);
}
@DataProvider(name = "excel")
public Object[][] getDataByExcel() throws IOException {
return new ExcelDataProvider().getExcelData("data/user.xlsx", "Sheet1");
}
public Object[][] getExcelData(String fileName, String sheetName) throws IOException {
FileInputStream inputStream = new FileInputStream(new File(fileName));
Workbook wbook = new XSSFWorkbook(inputStream);
Sheet sheet = wbook.getSheet(sheetName);
int rowcount = sheet.getLastRowNum();
System.out.println(rowcount);
List<String[]> dataList = new ArrayList<String[]>();
// 逐行读取,转化为一维数组
for (int i = 0; i <= rowcount; i++) {
// 得到每一行
Row row = sheet.getRow(i);
String[] fields = new String[row.getLastCellNum()];
// 把每一行单元格的数据,存储到数组中.
for (int j = 0; j < row.getLastCellNum(); j++) {
String temp = row.getCell(j).getStringCellValue();
fields[j] = temp;
// System.out.println(temp);
}
dataList.add(fields);
}
// 把List数组转换为二维数组
Object[][] data = new Object[dataList.size()][];
for (int i = 0; i < dataList.size(); i++) {
data[i] = dataList.get(i);
}
return data;
}
}
效果:
注意
(1)不想用表头的数据,直接把循环的初始值改为1即可。
(2)我们一般把获取数据的方法,单独在一个类中,@Test,@DataProvider,放在另一个类中。(不同的类有不同的用途)
(3)传进来一个文件fileName,可用如下方法得到他的后缀:
String type= fileName.substring(fileName.indexOf("."));
随后,可用if判断(字符串的equals方法)判断哪种方式。
- 数据库的相关内容,还没学到,学到后补充。
如何和实际应用相结合?
- 准备数据(txt、excel等)
- 准备数据提供者
- 加属性/形参