我试图通过动态输入要从中提取数据的工作表的名称,以这种方式重用现有的数据提供程序,将Excel文件中的数据加载到我的测试框架中。
示例:我正在从Login凭据表加载数据,该表代表成功登录测试的数据。第二个测试是失败的登录测试,它从InvalidLogin凭据表加载数据。第三个测试从第三个表UserInformation等中提取数据。我所遵循的udemy课程并没有真正涵盖这个主题,我觉得整个事情的实际实现也不是最好的,但我只是跟着它,因为这是我第一次处理Selenium和Excel。
主要问题似乎是将此工作表名称参数发送到作为数据提供者的getData方法。出于某种原因,我认为解决方案可能非常简单,只是我无法理解它。
我尝试了XML参数属性,但它并没有解决我的问题。我想根据测试动态发送此参数。
我已经尝试在我的测试方法和数据提供者方法上使用@Parameters注释,但这也不起作用。将其放在测试方法上的问题是因为我假设数据提供者注释也试图从Excel文件中检索String 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());
}
是否有方法将带有工作表名称的字符串作为参数传递到某个位置,以便测试获得相关信息?
选项A:
我建议您看看这里所描述的ITestContext。
提供以下两种测试方法:第一种是设置属性(=工作表名称)的测试方法,第二种是测试方法(取决于第一种方法),由数据提供程序驱动,该数据提供程序使用我们指定的工作表中的数据。
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");
}
.....
}
在本文中,我解释了如何从头开始设置selenium java maven testNG项目。
希望这对你有帮助。问候,
我需要向TestNG数据提供程序传递10多个参数,代码如下所示。。。 有谁能告诉我,如果我们需要使用DataProvider传递10个以上的参数,我们应该采取什么方法?是否有其他方法来声明测试方法的参数?
问题内容: 我是Spring的新手。 这是bean注册的代码: 这是我的bean类: 这是我执行操作的主要方法: 现在,我想用参数调用此构造函数,并且这些参数是在我的主要方法中动态生成的。这就是我想动态传递- 而不是像文件中声明的那样静态传递的意思。 问题答案: 请看一下构造函数注入。 此外,请查看IntializingBean和BeanPostProcessor,以了解Springbean的其他
我不熟悉Spring。 这是bean注册的代码: 这是我的豆子课: 这是我执行动作的主要方法: 现在我想用参数调用这个构造函数,这些参数是在我的主要方法中动态生成的。这就是我想动态传递的意思——而不是静态传递,就像我的文件中声明的那样。
问题内容: 我想将登录用户单击的sa 列表中的传递给twitter bootstrap 。我正在与 angularjs* 一起使用 grails ,其中数据是通过 angularjs 呈现的。 *** 组态 我的grails视图页面是 我的是 所以,我怎么能传递到? 问题答案: 我尝试如下。 我在 鼓励 按钮上打电话给angularjs控制器, 我设置的从angularjs控制器。 我提供了一个p
问题内容: 我正在使用testNG,Selenium和Jenkins建立测试自动化框架。该代码工作正常,它读取一个或多个csv文件并将其用作测试数据。我从詹金斯进行测试。 如您所见,浏览器,URL和CSV文件是硬编码的。我希望能够将这些作为参数传递。做这个的最好方式是什么?是否可以让他们通过詹金斯? 我正在考虑构建一个仪表板,在其中可以指定要使用哪种浏览器运行哪些测试(csv文件)。 这是我正在运
问题内容: 我将主类作为命令行参数传递给启动VM 现在我需要将命令行参数传递给该主类 有什么办法吗? 这就是我做的方式 这里的userVMargs是我的主类的类路径,也是该类的类路径,该类路径用于调用主类内部的类方法 和cmdLine拥有我的主类以及该类及其功能,我使用eclipse作为IDE来开发我的项目 问题答案: 如果要通过发送参数来启动VM,则应发送VM参数而不是程序参数。 程序参数是传递