I'm a little confused as to how best to implement a simple DataProvider, having not done so before.
I have a very simple comma delimited .csv file:
978KAL,625JBH,876SSH,452GSH
I simply need to read it in and iterate over the records, running the same test for each record until done.
My code so far:
String csvFile = "src/test/resources/registrationsData.csv";
BufferedReader br = null;
String line = "";
String cvsSplitBy = ",";
@DataProvider(name="getRegistrations")
private Object[] getCSVTestData() {
Object [] registrationsObject;
try {
br = new BufferedReader(new FileReader(csvFile));
while ((line = br.readLine()) != null) {
// use comma as separator
String [] registrations = line.split(cvsSplitBy);
System.out.println( registrations[0] + "," + registrations[1]);
}
} catch//File not found & IOException handling here
registrationsObject = new Object[][]{registrations};
return registrationsObject;
}
@Test(dataProvider = "getRegistrations")
public void getRegistrations(String registration){
Object[] objRegArray = getCSVTestData();
for(int i=0; objRegArray.length>i; i++){
//run tests for every record in the array (csv file)
}
}
I know that I need to use an Object array return type for the Data Provider method.
I'm unclear as to how (and/or the best way) to retrieve each record from the objRegArray object.
This is a basic Collections question I guess; can anyone point me the right way?
Check this code with my explanation below:
package click.webelement.testng;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Iterator;
import java.util.Scanner;
public class OneLineCSV {
final static String CSV_FILE = "/path_to_file/oneline.csv";
final static String DELIMETER = ",";
@DataProvider(name = "test")
public Iterator<Object[]> testDP(){
try {
Scanner scanner = new Scanner(new File(CSV_FILE)).useDelimiter(DELIMETER);
return new Iterator<Object[]>() {
@Override
public boolean hasNext() {
return scanner.hasNext();
}
@Override
public Object[] next() {
return new Object[]{scanner.next()};
}
};
} catch (FileNotFoundException e) {
e.printStackTrace();
return null;
}
}
@Test(dataProvider = "test")
public void testOneLineCSV(String value){
System.out.println(value);
}
}
So I would use Scanner
class hence it has the convenient facility to parse a string into tokens.
I would also use the capability to return Iterator<Object[]>
in your data provider since Scanner
is designed in that way. You simply wrap it with new Iterator that converts String
that is returned by Scanner.next()
to new Object[]{scanner.next}
.
Using Iterator
with Scanner
is really more comfortable since you may not know how many values you will have to provide. So you shouldn't care of defining array size.