Проблема заключается в вашем тестовом коде.
Вы получаете объект ITestContext
с помощью аннотированного метода @BeforeSuite
. Но когда вы используете фабрику в сочетании с поставщиком данных, TestNG сначала находит поставщик данных, связанный с вашим методом фабрики (в данном случае конструктором). Как только метод поставщика данных найден, он вызывает его для получения всех наборов данных, которые должны использоваться для итерации и создания экземпляров тестового класса. Поставщик данных в вашем случае ссылается на объект контекста (в данном случае mContext
), который может быть инициализирован только при вызове метода @BeforeSuite
. Метод @BeforeSuite
не вызывается до тех пор, пока не будет создан экземпляр (именно это пытается сделать метод фабрики)
Вот правильный способ сделать это.
В моем примере таблица Excel состоит из двух листов:
- работник
- ученик
Лист employee содержит следующие данные
+--------+--------------------+
| name | email |
+--------+--------------------+
| John | john@example.com |
| Rajeev | rajeev@example.com |
| Jack | jack@example.com |
+--------+--------------------+
и лист student содержит следующие данные.
+-------+--------+
| name | rollNo |
+-------+--------+
| Surya | 1 |
| Rajni | 2 |
| Kamal | 3 |
+-------+--------+
Тестовый класс, который использует фабрику и провайдера данных, который считывает из вышеупомянутой электронной таблицы
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.DataFormatter;
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.ss.usermodel.WorkbookFactory;
import org.testng.Assert;
import org.testng.ITestContext;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Factory;
import org.testng.annotations.Test;
public class TestclassSample {
private Map<String, String> data;
private static final String SHEET = "sheet";
private static final String FILENAME = "filename";
@Factory(dataProvider = "dp")
public TestclassSample(Map<String, String> data) {
this.data = data;
}
@Test
public void dataIsNotEmpty() {
System.err.println("Ensuring that " + data + " is not empty");
Assert.assertFalse(data.isEmpty());
}
@Test
public void dataHasAtleastTwoColumns() {
System.err.println("Ensuring that " + data + " has atleast 2 entries");
Assert.assertTrue(data.size() >= 2);
}
@DataProvider(name = "dp")
public static Object[][] getData(ITestContext context)
throws IOException, InvalidFormatException {
String filename = context.getCurrentXmlTest().getParameter(FILENAME);
if (filename == null || filename.trim().isEmpty()) {
throw new IllegalArgumentException("File name was not present as a parameter");
}
Workbook workbook = WorkbookFactory.create(new File(filename));
String sheet = context.getCurrentXmlTest().getParameter(SHEET);
if (sheet == null || sheet.trim().isEmpty()) {
throw new IllegalArgumentException("Sheet name was not present as a parameter");
}
Sheet worksheet = workbook.getSheet(sheet);
DataFormatter dataFormatter = new DataFormatter();
Row headingRow = worksheet.getRow(0);
List<String> heading = new ArrayList<>();
for (Cell cell : headingRow) {
heading.add(dataFormatter.formatCellValue(cell));
}
List<Map<String, String>> information = new ArrayList<>();
for (int i = 1; i < worksheet.getLastRowNum(); i++) {
Map<String, String> data = new HashMap<>();
int index = 0;
for (Cell cell : worksheet.getRow(i)) {
data.put(heading.get(index++), dataFormatter.formatCellValue(cell));
}
information.add(data);
}
Object[][] data = new Object[information.size()][1];
for (int i = 0; i < information.size(); i++) {
data[i] = new Object[] {information.get(i)};
}
workbook.close();
return data;
}
}
xml комплекта testng выглядит следующим образом
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="53358567_suite" parallel="false" verbose="2" group-by-instances="true">
<parameter name="sheet" value="student"/>
<parameter name="filename" value="src/test/resources/53358567.xlsx"/>
<test name="53358567_test">
<classes>
<class name="com.rationaleemotions.stackoverflow.qn53358567.TestclassSample"/>
</classes>
</test>
</suite>
Вывод как показано ниже
...
... TestNG 7.0.0-beta1 by Cédric Beust (cedric@beust.com)
...
Ensuring that {name=Rajni, rollNo=2} has atleast 2 entries
Ensuring that {name=Rajni, rollNo=2} is not empty
Ensuring that {name=Surya, rollNo=1} has atleast 2 entries
Ensuring that {name=Surya, rollNo=1} is not empty
PASSED: dataHasAtleastTwoColumns
PASSED: dataIsNotEmpty
PASSED: dataHasAtleastTwoColumns
PASSED: dataIsNotEmpty
===============================================
53358567_test
Tests run: 4, Failures: 0, Skips: 0
===============================================
===============================================
53358567_suite
Total tests run: 4, Passes: 4, Failures: 0, Skips: 0
===============================================
Process finished with exit code 0