Java TestNG:使用 Dataprovider 遍历数组
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/22021793/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
TestNG: Iterate through array using the Dataprovider
提问by Learner
I'm conducting Automation testing using Selenium Webdriver, this code is for TestNg dataprovider
, Summary: I am taking data from Excel sheet to data,
it's working fine. When I'm debugging the code, I'm getting TestData as testGoogle1(String search1, String Search2)
for 1st Iteration it Search1 = Webdriver, Search2 = Qtp, so on,,,,
What I want is that it should directly return the array of values something like testGoogle1(String search[])
so that in the @Test
itself I can add my function iterate all the rows and columns and test them.
我正在使用 Selenium Webdriver 进行自动化测试,此代码用于 TestNg dataprovider
,摘要:我正在将数据从 Excel 工作表获取到数据,它工作正常。当我调试代码时,我得到 TestData 作为testGoogle1(String search1, String Search2)
第一次迭代它Search1 = Webdriver, Search2 = Qtp, so on,,,,
我想要的是它应该直接返回值的数组,testGoogle1(String search[])
这样@Test
我就可以在它本身添加我的函数迭代所有行和列和测试它们。
Can anyone please give me the idea how to write it.
任何人都可以请给我的想法如何写它。
Test Data sheet
测试数据表
here is my code
这是我的代码
package ExcelTest;
import com.thoughtworks.selenium.*;
import static org.testng.AssertJUnit.*;
import java.io.IOException;
import jxl.Cell;
import jxl.CellType;
import jxl.Sheet;
import jxl.Workbook;
import jxl.read.biff.BiffException;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import org.testng.annotations.AfterTest;
import java.io.File;
import java.io.FileInputStream;
import java.util.Iterator;
import jxl.*;
public class Sample{
WebDriver driver;
@BeforeTest
public void startTest(){
driver = Startup.basic();
}
@DataProvider(name = "DP1")
public Object[][] createData1() throws Exception{
Object[][] retObjArr=getTableArray("G:\Selenium Jar Files\TestData\Data.xls","DataPool");
return(retObjArr);
}
@Test (dataProvider = "DP1")
public void testGoogle1(String search1, String Search2) throws Exception{
//selenium.open("http://www.google.co.in/");
// driver.get("http://www.google.co.in/");
//String hello = search.length;
//for(int i=0; i< search.length ;i++)
//{
System.out.println("param " +search);
Thread.sleep(3000);
System.out.println("Opened");
WebElement element = driver.findElement(By.name("q"));
element.sendKeys(search);
element.submit();
System.out.println("Clicked");
}
//}
@AfterClass
public void tearDown() throws Exception {
//selenium.stop();
}
public String[][] getTableArray(String xlFilePath,String sheetName) throws Exception{
String[][] tabArray=null;
File inputWorkbook = new File(xlFilePath);
Workbook w;
int startRow,startCol, endRow, endCol,ci,cj;
try {
//w = Workbook.
w = Workbook.getWorkbook(inputWorkbook);
// Get the first sheet
Sheet sheet = w.getSheet(sheetName);
// Loop over first 10 column and lines
endRow = sheet.getRows();
endCol = sheet.getColumns();
tabArray=new String[endRow-1][endCol-1];
ci=0;
for (int i=1;i<endRow;i++,ci++){
cj=0;
for (int j=1;j<endCol;j++,cj++){
Cell cell = sheet.getCell(j, i);
tabArray[ci][cj] = cell.getContents();
}
// System.out.println("");
}
//file.close();
}
catch (Exception e)
{
e.printStackTrace();
}
return(tabArray);
}
}
Can anyone please share any idea ? Thanks
任何人都可以分享任何想法吗?谢谢
Edited Code:
编辑代码:
public class Sample{
WebDriver driver;
@BeforeTest
public void startTest(){
driver = Startup.basic();
}
@DataProvider(name = "DP1")
public Object[][][] createData1() throws Exception{
Object[][][] retObjArr=getTableArray("G:\Selenium Jar Files\TestData\Data.xls","DataPool");
return (retObjArr);
}
@Test (dataProvider = "DP1")
public void testGoogle1(String search, String het) throws Exception{
System.out.println("param " +search);
Thread.sleep(3000);
System.out.println("Opened");
WebElement element = driver.findElement(By.name("q"));
element.sendKeys(search);
element.submit();
System.out.println("Clicked");
}
//}
@AfterClass
public void tearDown() throws Exception {
//selenium.stop();
}
public Object[][][] getTableArray(String xlFilePath,String sheetName) throws Exception{
Object[][] tabArray=null;
File inputWorkbook = new File(xlFilePath);
Workbook w;
int startRow,startCol, endRow, endCol,ci,cj,ck;
try {
//w = Workbook.
w = Workbook.getWorkbook(inputWorkbook);
// Get the first sheet
Sheet sheet = w.getSheet(sheetName);
// Loop over first 10 column and lines
endRow = sheet.getRows();
endCol = sheet.getColumns();
tabArray=new String[endRow-1][endCol-1];
ci=0;
for (int i=1;i<endRow;i++,ci++){
cj=0;
for (int j=1;j<endCol;j++,cj++){
Cell cell = sheet.getCell(j, i);
tabArray[ci][cj] = cell.getContents();
}
// System.out.println("");
}
//file.close();
}
catch (Exception e)
{
e.printStackTrace();
}
return(tabArray); /// Here Getting the error **Type mismatch: cannot convert from Object[][] to Object[][][]**
}
}
回答by Nathan Merrill
This is how a @DataProvider
works, assuming I have the following array:
这就是 a 的@DataProvider
工作方式,假设我有以下数组:
[[value1, value2],
[value3, value4],
[value5, value6]]
Note that there are 3 rows and 2 columns. The Test will be run 3 times, and passed in 2 values each time. It doesn't matter what the value is.
请注意,有 3 行和 2 列。测试将运行 3 次,每次传递 2 个值。值是什么并不重要。
Now, if you want the test to only be run once, your array should look like this:
现在,如果您希望测试只运行一次,您的数组应如下所示:
[[value1]]
We can make value1
to be whatever we want it to be, so if value1
is the array above, then it will pass in the entire array to the dataProvider. Thus, your return statement should return {{tabArray}}
我们可以让它value1
成为我们想要的任何东西,所以如果value1
是上面的数组,那么它会将整个数组传递给 dataProvider。因此,您的 return 语句应该返回{{tabArray}}
回答by thekevinmonster
Looking at your code, you are trying to create a dataprovider function that returns Object[][][]. You cannot do that; the dataprovider function must return either Object[][] (a two dimensional array of any Object), or an Iterator which will perform the same function but in a slightly different way.
查看您的代码,您正在尝试创建一个返回 Object[][][] 的 dataprovider 函数。你不能这样做; dataprovider 函数必须返回 Object[][](任何 Object 的二维数组),或一个 Iterator,它将执行相同的功能,但方式略有不同。
You can certainly nest another array inside of the 2D array that is returned; that is why it is Object[][] and not a specific type.
您当然可以在返回的二维数组中嵌套另一个数组;这就是为什么它是 Object[][] 而不是特定类型的原因。
Also make sure you construct your return result correctly. For example, you can't do the following because that does not construct the Object[][] array:
还要确保正确构建返回结果。例如,您不能执行以下操作,因为这不会构造 Object[][] 数组:
return {{myArray}};
Instead, you would do this:
相反,你会这样做:
return new Object[][]{{myArray}};
回答by djangofan
I think jxlis harder than it needs to be. I wrote an example of a TestNG DataProvider reading Excel datausing Apache MetaModel(which recently became a full fledged Apache project) , and you can find that here.
我认为jxl比它需要的更难。我写了一个 TestNG DataProvider使用Apache MetaModel读取 Excel 数据的示例(它最近成为一个成熟的 Apache 项目),您可以在此处找到。
public static Object[][] getCsvData( File csvFile )
{
CsvConfiguration conf = new CsvConfiguration( 1 );
DataContext csvContext = DataContextFactory.createCsvDataContext( csvFile, conf );
Schema schema = csvContext.getDefaultSchema();
Table[] tables = schema.getTables();
Table table = tables[0]; // a representation of the csv file name including extension
DataSet dataSet = csvContext.query()
.from( table )
.selectAll()
.where("run").eq("Y")
.execute();
List<Row> rows = dataSet.toRows();
Object[][] myArray = get2ArgArrayFromRows( rows );
return myArray;
}
And second part of that:
第二部分:
public static Object[][] get2ArgArrayFromRows( List<Row> rows ) {
Object[][] myArray = new Object[rows.size()][2];
int i = 0;
SelectItem[] cols = rows.get(0).getSelectItems();
for ( Row r : rows ) {
Object[] data = r.getValues();
for ( int j = 0; j < cols.length; j++ ) {
if ( data[j] == null ) data[j] = ""; // force empty string where there are NULL values
}
myArray[i][0] = cols;
myArray[i][1] = data;
i++;
}
logger.info( "Row count: " + rows.size() );
logger.info( "Column names: " + Arrays.toString( cols ) );
return myArray;
}
And an example of a test that uses this DataProvider:
以及使用此 DataProvider 的测试示例:
@Test( dataProvider = "csv" )
public void testPrintCsvRowToLog( SelectItem[] cols, Object[] data ) {
String theCols = Joiner.on("|").join( cols );
String aRow = Joiner.on("|").join( data );
logger.info( theCols );
logger.info( aRow );
}
回答by Rajan Domala
You cannot use TestNg Parameter and Dataprovider for @Test annotation.
您不能将 TestNg Parameter 和 Dataprovider 用于 @Test 注释。
Better to use DataProvider annotation for BeforeTest/Beforeclass annotation and Use @Parameter annotataion for @Test annotation
最好对 BeforeTest/Beforeclass 注释使用 DataProvider 注释,对 @Test 注释使用 @Parameter 注释