如何将动态参数传递给testNG中的dataProvider方法
How to pass dynamic parameter to dataProvider method in testNG
我正在尝试通过动态输入从中提取数据的 sheet 的名称,将数据从 Excel 文件加载到我的测试框架中,以这种方式重用现有数据提供程序。
示例:我正在从 LoginCredentials sheet 加载数据,它表示成功登录测试的数据。
第二个测试是失败的登录测试,它从 InvalidLoginCredentials sheet 加载数据。
第三个测试从第三个 sheet UserInformation 等中提取数据。
我正在学习的 udemy 课程并没有真正涵盖这个主题,我觉得整个事情的实际实施也不是最好的,但我只是接受了它,因为这是我第一次处理 Selenium 和 Excel .
主要问题似乎是将此 sheet 名称参数发送到作为数据提供者的 getData 方法。出于某种原因,我认为解决方案可能非常简单,只是我无法全神贯注。
我试过 XML 参数属性,但它没有解决我的问题。我想根据测试动态发送此参数。
我已经尝试在我的测试方法和数据提供者方法上使用@Parameters 注释,但这也不起作用。将它放在测试方法上的问题是因为我假设数据提供者注释也在尝试从 Excel 文件中检索字符串 sheetName 而我的测试甚至不会 运行。
在数据提供者方法本身上使用它不是一种选择,因为我必须创建与发送的参数一样多的数据提供者方法(这会破坏重用我现有数据提供者的全部意义)。
从excel文件中获取数据的方法
public Object[][] testData(String excelPath, String sheetName) {
Object[][] data = null;
try {
ExcelUtil excelUtil = new ExcelUtil(excelPath, sheetName);
XSSFWorkbook workbook = new XSSFWorkbook(excelPath);
XSSFSheet sheet = workbook.getSheet(sheetName);
int rowCount = excelUtil.getRowCount();
int colCount = excelUtil.getColCount();
data = new Object[rowCount - 1][colCount];
for (int i = 1; i < rowCount; i++) {
Row row = sheet.getRow(i);
for (int j = 0; j < colCount; j++) {
Cell cell = row.getCell(j);
switch (cell.getCellType()) {
case STRING:
data[i - 1][j] = excelUtil.getCellDataString(i, j);
break;
case NUMERIC:
data[i - 1][j] = String.valueOf(excelUtil.getCellDataNumeric(i, j));
break;
}
}
}
} catch (Exception ex) {
LOGGER.error("Error while loading data from Excel file: " + ex.getMessage());
}
return data;
}
dataProvider 方法本身
@DataProvider(name = "TeamoLoginData")
public Object[][] getData(){
String excelPath = "src/main/java/apps/teamo/testdata/Book 1.xlsx";
return testData(excelPath, "LoginCredentials");
}
测试方法:
@Test(dataProvider = "TeamoLoginData", dataProviderClass = ExcelDataProvider.class)
public void loginSuccessful(Method method, String username, String password) {
ExtentTestManager.startTest(methodName, "Successful login");
TeamoLoginPage teamoLoginPage = new TeamoLoginPage(getDriver());
TeamoHomePage teamoHomePage = new TeamoHomePage(getDriver());
getDriver().get(PropertyManager.getInstance().getBaseURL());
teamoLoginPage.enterUsername(username);
teamoLoginPage.enterPassword(password);
teamoLoginPage.signIn();
Assert.assertTrue(teamoHomePage.changeLogIsDisplayed());
}
有没有办法在某处传递名称为sheet的字符串作为参数,以便测试获取相关信息?
选项A:
我建议关注 ITestContext
,因为它一直是 described here。
提供以下两种@Test
方法:
第一个测试方法设置属性 (=sheet name) ,
第二个 @Test 方法(取决于第一个)- 由数据提供者驱动,该数据提供者正在使用我们指定的 sheet 中的数据。
import org.testng.ITestContext;
import org.testng.Reporter;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
public class DemoTestClass {
@Test
public void testTabnameSetting() {
//Simulating toggling between multiple flows.
String tabName = "LoginCredentials";
Reporter.getCurrentTestResult().getTestContext().setAttribute("sheetName", tabName);
}
@Test(dependsOnMethods = "testTabnameSetting", dataProvider = "getData")
public void loginSuccess(String username, String pass) {
//test method logic goes here. .....
}
@DataProvider
public Object[][] getData(ITestContext context) {
String sheetNameToParse = context.getAttribute("sheetName").toString();
String excelPath = "src/main/java/apps/teamo/testdata/Book 1.xlsx";
return testData(excelPath, sheetNameToParse);
}
}
============
选项 B:
您可以为不同的目的定义不同的测试(在套件中),例如
public class DemoTestClass {
@Test(dataProvider = "getData")
public void testSheetA(String username, String pass){
....}
@Test(dataProvider = "getData")
public void
testSheetB(String username, String pass){...}
@Test(dataProvider = "getData")
public void
testSheetC(String username, String pass){....}
}
和其他选项 - 只是 re-organized 您的数据提供者将分析测试名称,因此 - 为测试提供适当的 sheet 名称:
@DataProvider
public Object[][] getData(ITestNGMethod testContext)
{
String excelPath = "src/main/java/apps/teamo/testdata/Book 1.xlsx";
if(testContext.getMethodName().equals("testSheetA"))
{
return testData(excelPath, "sheetA");
}
else if(testContext.getMethodName().equals("testSheetB"))
{
return testData(excelPath, "sheetB");
}
.....
}
在这篇文章中,我解释了如何从头开始 to set-up selenium java maven testNG project。
希望对您有所帮助。
亲切的问候,
我正在尝试通过动态输入从中提取数据的 sheet 的名称,将数据从 Excel 文件加载到我的测试框架中,以这种方式重用现有数据提供程序。
示例:我正在从 LoginCredentials sheet 加载数据,它表示成功登录测试的数据。 第二个测试是失败的登录测试,它从 InvalidLoginCredentials sheet 加载数据。 第三个测试从第三个 sheet UserInformation 等中提取数据。 我正在学习的 udemy 课程并没有真正涵盖这个主题,我觉得整个事情的实际实施也不是最好的,但我只是接受了它,因为这是我第一次处理 Selenium 和 Excel .
主要问题似乎是将此 sheet 名称参数发送到作为数据提供者的 getData 方法。出于某种原因,我认为解决方案可能非常简单,只是我无法全神贯注。
我试过 XML 参数属性,但它没有解决我的问题。我想根据测试动态发送此参数。
我已经尝试在我的测试方法和数据提供者方法上使用@Parameters 注释,但这也不起作用。将它放在测试方法上的问题是因为我假设数据提供者注释也在尝试从 Excel 文件中检索字符串 sheetName 而我的测试甚至不会 运行。
在数据提供者方法本身上使用它不是一种选择,因为我必须创建与发送的参数一样多的数据提供者方法(这会破坏重用我现有数据提供者的全部意义)。
从excel文件中获取数据的方法
public Object[][] testData(String excelPath, String sheetName) {
Object[][] data = null;
try {
ExcelUtil excelUtil = new ExcelUtil(excelPath, sheetName);
XSSFWorkbook workbook = new XSSFWorkbook(excelPath);
XSSFSheet sheet = workbook.getSheet(sheetName);
int rowCount = excelUtil.getRowCount();
int colCount = excelUtil.getColCount();
data = new Object[rowCount - 1][colCount];
for (int i = 1; i < rowCount; i++) {
Row row = sheet.getRow(i);
for (int j = 0; j < colCount; j++) {
Cell cell = row.getCell(j);
switch (cell.getCellType()) {
case STRING:
data[i - 1][j] = excelUtil.getCellDataString(i, j);
break;
case NUMERIC:
data[i - 1][j] = String.valueOf(excelUtil.getCellDataNumeric(i, j));
break;
}
}
}
} catch (Exception ex) {
LOGGER.error("Error while loading data from Excel file: " + ex.getMessage());
}
return data;
}
dataProvider 方法本身
@DataProvider(name = "TeamoLoginData")
public Object[][] getData(){
String excelPath = "src/main/java/apps/teamo/testdata/Book 1.xlsx";
return testData(excelPath, "LoginCredentials");
}
测试方法:
@Test(dataProvider = "TeamoLoginData", dataProviderClass = ExcelDataProvider.class)
public void loginSuccessful(Method method, String username, String password) {
ExtentTestManager.startTest(methodName, "Successful login");
TeamoLoginPage teamoLoginPage = new TeamoLoginPage(getDriver());
TeamoHomePage teamoHomePage = new TeamoHomePage(getDriver());
getDriver().get(PropertyManager.getInstance().getBaseURL());
teamoLoginPage.enterUsername(username);
teamoLoginPage.enterPassword(password);
teamoLoginPage.signIn();
Assert.assertTrue(teamoHomePage.changeLogIsDisplayed());
}
有没有办法在某处传递名称为sheet的字符串作为参数,以便测试获取相关信息?
选项A:
我建议关注 ITestContext
,因为它一直是 described here。
提供以下两种@Test
方法:
第一个测试方法设置属性 (=sheet name) ,
第二个 @Test 方法(取决于第一个)- 由数据提供者驱动,该数据提供者正在使用我们指定的 sheet 中的数据。
import org.testng.ITestContext;
import org.testng.Reporter;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
public class DemoTestClass {
@Test
public void testTabnameSetting() {
//Simulating toggling between multiple flows.
String tabName = "LoginCredentials";
Reporter.getCurrentTestResult().getTestContext().setAttribute("sheetName", tabName);
}
@Test(dependsOnMethods = "testTabnameSetting", dataProvider = "getData")
public void loginSuccess(String username, String pass) {
//test method logic goes here. .....
}
@DataProvider
public Object[][] getData(ITestContext context) {
String sheetNameToParse = context.getAttribute("sheetName").toString();
String excelPath = "src/main/java/apps/teamo/testdata/Book 1.xlsx";
return testData(excelPath, sheetNameToParse);
}
}
============
选项 B: 您可以为不同的目的定义不同的测试(在套件中),例如
public class DemoTestClass {
@Test(dataProvider = "getData")
public void testSheetA(String username, String pass){
....}
@Test(dataProvider = "getData")
public void
testSheetB(String username, String pass){...}
@Test(dataProvider = "getData")
public void
testSheetC(String username, String pass){....}
}
和其他选项 - 只是 re-organized 您的数据提供者将分析测试名称,因此 - 为测试提供适当的 sheet 名称:
@DataProvider
public Object[][] getData(ITestNGMethod testContext)
{
String excelPath = "src/main/java/apps/teamo/testdata/Book 1.xlsx";
if(testContext.getMethodName().equals("testSheetA"))
{
return testData(excelPath, "sheetA");
}
else if(testContext.getMethodName().equals("testSheetB"))
{
return testData(excelPath, "sheetB");
}
.....
}
在这篇文章中,我解释了如何从头开始 to set-up selenium java maven testNG project。
希望对您有所帮助。 亲切的问候,