TestNG DataProvider reading test data from the tes

2019-02-14 13:31发布

问题:

Is it possible for a TestNG DataProvider to read test data from the testng.xml config file? Or is this unrealistic for some reason? I would like to be able to read test data from that file at the suite level and class level.

So, given a testing.xml file like this (which I am unsure is realistic or not), how would I do this? I have written a DataProvider using XStream (or Jackson) before and so I am well versed in my own custom .xml format, but sticking to the strict format of the testing.xml is where I am worried about this.

The following testing.xml is obvious invalid but I am just trying to show the kind of thing I would like to do:

<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" > 
<suite name="TestAll"> 
  <parameter name="hubUrl" value="http://localhost:4444/wd/hub"/>
  <parameter name="reportFile" value="CustomReport.html"/>
  <test name="etsy">
    <parameter name="reportFile" value="CustomReport.html"/>
    <classes>
      <class name="qa.examples.suite.TestSearch">
        <parameter name="appUrl"  value="http://etsy.com" type="java.lang.String"/> 
        <parameter name="browser"  value="Firefox" type="java.lang.String"/>    
        <parameter name="testEnabled" value="true" type="java.lang.Boolean"/> 
        <methods>                 
          <include name="testEtsySearch"/>
            <tests>
              <test>
                <parameter name="testNum" value="1" type="java.lang.Integer"/>
                <parameter name="searchTerm" value="cell phone" type="java.lang.String"/>
                <parameter name="searchTerm" value="batteries" type="java.lang.String"/>
              </test>
              <test>
                <parameter name="testNum" value="2" type="java.lang.Integer"/>
                <parameter name="searchTerm" value="buttons" type="java.lang.String"/>
                <parameter name="searchTerm" value="metal" type="java.lang.String"/>
              </test>
            </tests>
          </include>                       
        </methods> 
      </class>
      <class name="qa.examples.suite.TestFilters" />
    </classes>
    </test> 
</suite>

So, is something like this possible? If so, how would you do it?

回答1:

Try to pass ITestContext as a data provider parameter. Something like:

@DataProvider(name = "DataProvider")
public static Object[][] Provider(ITestContext context) throws Exception
{
    String dataFile = context.getCurrentXmlTest().getParameter("dataFile");
}

Suite xml

<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" > 
<suite name="suite"> 
  <parameter name="param1" value="val1"/>
  <test name="test">
    <parameter name="param2" value="val2"/>
    <classes>
      <class name="test.TestClass1" />
    </classes>
  </test> 
</suite>

test class

package test;
import java.util.Map;
import org.testng.ITestContext;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;

public class TestClass1 {

@DataProvider(name="Provider")
public Object[][] provider(ITestContext context)
{
 Map<String, String> testParams = context.getCurrentXmlTest().getLocalParameters();
 Map<String, String> suiteParams=context.getCurrentXmlTest().getSuite().getParameters();

 return new Object[][]{{suiteParams.get("param1"), testParams.get("param2")}};
}

@Test(dataProvider="Provider")
public void test1(String param1, String param2)
{
 System.out.println("Param1: " + param1);
 System.out.println("Param2: " + param2);
}

}

Output

[TestNG] Running:
/home/nightmare/workspace/test/suite.xml

Param1: val1
Param2: val2

===============================================
suite
Total tests run: 1, Failures: 0, Skips: 0
===============================================


回答2:

I am currently passing only Suite Level Parameters from my XML. This is how I would do it - I would create a class - readParamsFromXML.

@Parameters( { "suiteParam1", "suiteParam2" } )
@BeforeSuite
public void getSuiteLevelParamsFromXML(
    @Optional("defaultValueForSuiteParam1")String SuiteParam1, 
    @Optional("defaultValueForSuiteParam2")String SuiteParam2 ) {
     <Some  Logic here based on the params passed>
}

I would extend a similar logic to read params at Test level & Method level by creating methods like - getTestLevelParamsFromXML & getMethodLevelParamsFromXML. I would add annotations like @BeforeClass & @BeforeMethod respectively for the above methods.

Now, all my test cases should extend readParamsFromXML class. This way - suite, test & class level parameters passed from XML could be available in test methods

Might not be the best way to get things done. But works perfectly for me.