是否可以使用相同的数据提供者将动态数量的参数传递给相同的testng测试?

时间:2017-06-11 04:56:17

标签: java testng testng-dataprovider

我有一个testng测试方法和数据提供程序。我想让测试用例可以重复使用要测试此功能的多个客户端。唯一的问题是该功能在不同的客户端上的工作方式不同,我必须为不同的客户端为同一功能提供不同数量的输入,最终结果对所有客户端都相同。

目前,我正在通过为具有此功能的多个客户端的数据提供程序定义多个测试方法来实现此目的。

实施例: -

@DataProvider(name="dp1")
public Object[][] getDataForClient1()
{
   //return data
}

@Test(dataProvider="dp1", groups={"client1"})
public void transferCredit(String senderId,String receiverId,String amount,String expectedResult)
{
   //Perform operation
}

@DataProvider(name="dp2")
public Object[][] getDataForClient2()
{
   //return data
}

@Test(dataProvider="dp2", groups={"client2"})
public void transferCredit(String senderId,String receiverId,String amount,String paymentReference,String expectedResult)
{
   //Perform operation
}

我开发了一个通用的测试逻辑来处理不同的参数集。我无法做的是为不同的参数集重用相同的测试方法。

我想像以下一样

@DataProvider(name="dp")
public Object[][] getData()
{
   //return data
}

@Test(dataProvider="dp", groups={"client1,client2"})
public void transferCredit(String ... params)
{
   //Perform operation
}

但这样做会给testng异常,即参数不匹配。那么在TestNG中有没有办法做到这一点?

4 个答案:

答案 0 :(得分:1)

您可以将数据包装为对象。正如我所看到的,一些参数保持不变,而一些变化。因此,创建一个包含senderid,receiverid,params和所有超集的类 - 仅根据调用dataprovider的方法设置所需的数据并发送这些对象的数组。

答案 1 :(得分:1)

另一个选择(除了已经在这里分享的那个)是做这样的事情

public class TestSample {

    @Test(dataProvider = "dp")
    public void testMethod(Object object) {
        if (object instanceof String[]) {
            System.err.println("Incoming array was " + Arrays.toString((String[]) object));
        }
        if (object instanceof String) {
            System.err.println("Incoming string " + object);
        }

    }

    @DataProvider(name = "dp")
    public Object[][] getData() {
        return new Object[][]{
                {new String[]{"TestNG", "JUnit"}},
                {"Cedric Beust"}
        };
    }
}

但说实话,我不认为这是一个可以在TestNG中受理的功能请求。只是我个人的意见。

答案 2 :(得分:0)

虽然不知道有一个非常干净/直接的功能可以访问,但很少有建议 -

  1. 使用DataProvider中的数据超集,当您使用不同方法使用它们时,可以忽略不需要所有参数的额外参数。样本 -

    @DataProvider(name="dp")
    public Object[][] getData() {
       //return data
    }
    
    @Test(dataProvider="dp1", groups={"client1"})
    public void transferCredit(String senderId,String receiverId,String amount,String expectedResult) {
       //Perform operation; Ignore paymentReference
    }
    
    @Test(dataProvider="dp", groups={"client2"})
    public void transferCredit(String senderId,String receiverId,String amount,String paymentReference,String expectedResult) {
        //Perform operation
    }
    
  2. 您可以使用Method获取DataProvider中调用方法的名称,并相应地调整返回对象。这是documentation和围绕它的样本。

      

    如果您将@DataProvider声明为采用java.lang.reflect.Method   作为第一个参数,TestNG将为此传递当前的测试方法   第一个参数。这在几种测试方法中特别有用   使用相同的@DataProvider,您希望它返回不同的值   取决于它为哪种测试方法提供数据。

    @DataProvider(name="dp")
    public Object[][] getDataForClient2(Method m) {
       if(m.getName().equals("transferCreditM1") {
           //do X
       } else { 
           //do Y
       }     
    }
    

答案 3 :(得分:0)

读取现有的testng.xml文件,在运行时对其进行修改并执行

以下代码的作用: 我想在运行时为每个参数添加一个参数列表。这些参数作为maven运行时参数传递。使用System.getProperty()方法读取它们,如下所示。然后将这些参数添加到内部,并成功运行testng。可以根据您的要求进行扩展。

下面的代码读取testng.xml文件并将参数添加到

List<String> parameters = new ArrayList<>();
parameters = Arrays.asList(System.getProperty("parameters").split(",");

TestNG tng = new TestNG();
File initialFile = new File("testng.xml");
InputStream inputStream = FileUtils.openInputStream(initialFile);
Parser p = new Parser(inputStream);
List<XmlSuite> suites = p.parseToList();
for(XmlSuite suite:suites){
    List<XmlTest> tests = suite.getTests();
    for (XmlTest test : tests) {
         for (int i = 0; i < parameters.size(); i++) {
            HashMap<String, String> parametersMap = new HashMap<>();
            parametersMap.put("parameter",parameters.get(i));
            test.setParameters(parametersMap);
        }
    }
}
tng.setXmlSuites(suites);
tng.run();