java - 如何将动态参数传递给testNG中的dataProvider方法

标签 java excel selenium apache-poi testng

我正在尝试通过动态输入从中提取数据的工作表的名称,将数据从 Excel 文件加载到我的测试框架中,并以这种方式重用现有的数据提供程序。

示例:我正在从 LoginCredentials 表加载数据,该表表示成功登录测试的数据。 第二个测试是失败的登录测试,它从 InvalidLoginCredentials 表加载数据。 第三个测试从第三个表 UserInformation 等中提取数据。 我参加的 udemy 类(class)并没有真正涵盖这个主题,我觉得整个事情的实际实现也不是最好的,但我只是继续它,因为这是我第一次处理 Selenium 和 Excel。

主要问题似乎是将这个工作表名称参数发送到数据提供者的 getData 方法。出于某种原因,我认为解决方案可能非常简单,只是我无法理解它。

我尝试了 XML 参数属性,但它没有解决我的问题。我想根据测试动态发送这个参数。

我尝试在我的测试方法和数据提供程序方法上使用 @Parameters 注释,但这也不起作用。将其放在测试方法上的问题是因为我假设 dataprovider 注释也尝试从 Excel 文件中检索 StringsheetName,而我的测试甚至无法运行。

在数据提供程序方法本身上使用它不是一个选项,因为我必须创建与发送的参数一样多的数据提供程序方法(这会破坏重用现有数据提供程序的全部意义)。

从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());
    }

有没有办法将带有工作表名称的字符串作为参数传递到某处,以便测试获取相关信息?

最佳答案

选项A:

我建议您关注 ITestContext,因为它一直是 described here .

提供以下两个@Test方法: 第一个测试方法设置属性(=工作表名称), 第二个 @Test 方法(取决于第一个) - 由数据提供者驱动,该数据提供者消耗我们指定的工作表中的数据。

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){....}

}

其他选项 - 只是重新组织您的数据提供者,它将分析测试名称,因此 - 提供测试适当的工作表名称:

@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从头开始。

希望这对您有帮助。 亲切的问候,

关于java - 如何将动态参数传递给testNG中的dataProvider方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57091995/

相关文章:

java - 为什么测试需要永远执行

excel - 如果没有边框,为什么范围的边框宽度为 xlThin

excel - 将工作表复制到多个工作簿 - 公式引用

c# - Atata - 无法定位元素,使用 Table<> 类

ruby-on-rails - Capybara-selenium 故障并重定向 example.com/when 没有一切都是绿色的

java - 如何在 Linux、Mac 和 Windows 上制作安装程序?

java - 在java中自动生成ID

使用 DATEVALUE 函数时 Excel #Value 错误

javascript - 在 Selenium WebDriver 中使用 execute_async_script

java - 如何使用 Java Swing/awt 将标签放在面板内的单选按钮下