0

I am currently trying to write some automation tests using TestNG, which will verify some users actions on a website, so the tests are end-to-end functional tests as opposed to unit tests.

I have created an XML file which will hold the test data (the structure of this XML file will not change). The test script will read the information from the test file and pass that into a DataProvider, which then feeds the @Tests. The problem is - the dataprovider appears to be pumping each @Test method with every instance of the test data, and it is not running the tests in sequence.

I have attached the code - please could someone advice if my approach is correct, or what needs to be tweaked in the code to make this runnable for every set of test data.

Test Data File

<TestData>
<test>
    <username>letmein</username>
    <password>ok!</password>
    <product>tesco</product>
    <ordertype>Market</ordertype>
    <quantity>1000</quantity>
    <side>Buy</side>
</test>
<test>
    <username>letmein</username>
    <password>ok!</password>
    <product>barc</product>
    <ordertype>RFQ</ordertype>
    <quantity>100</quantity>
    <side>Buy</side>
</test>

The dataprovider reads this test data and passes it into an Object[][]

The automation test script is as follows;

public class PlaceOrderTestScript {
InitiateTesting x;
static TestDataProvider y;
static WebDriver driver;
boolean loggedin = false;

@Parameters("browser")
@BeforeTest
public void beforeMethod(String browser) throws Exception {
    x = new InitiateTesting();  
    y = new TestDataProvider(); 
    driver = x.launch(browser);  //select driver, browser and launch website
}

@DataProvider
public static Object[][] dp(ITestContext context) throws Exception {        
    String testdatalocation = context.getCurrentXmlTest().getParameter("placeordertestdata"); //suite.xml holds details of the test data file location
    Object[][] data = y.Provider(testdatalocation);
    return data;
}

@Test (dataProvider = "dp")
public void SignIn(String username, String password, String product, String ordertype, String quantity, String side) throws Exception {
    System.out.println("Log into site");
    // only run this test once
    if (loggedin == false) {
        LogIn_Page.txtbx_UserName(driver).sendKeys(username);
        LogIn_Page.txtbx_Password(driver).sendKeys(password);
        LogIn_Page.btn_LogIn(driver).click();
        Thread.sleep(5000); //pause for x seconds and let site load for the first time
        loggedin = true;
    }
}

@Test (dependsOnMethods={"SignIn"}, dataProvider = "dp")
public void SearchForProduct(String username, String password, String product, String ordertype, String quantity, String side) {
    // search for <product>
}

@Test (dependsOnMethods={"Search"}, dataProvider = "dp")
public void PlaceOrder(String username, String password, String product, String ordertype, String quantity, String side) {
    //Place order
}

@Test (dependsOnMethods={"PlaceOrder"}, dataProvider = "dp")
public void ValidateQuantityAmount(String username, String password, String product, String ordertype, String quantity, String side) {
    //check results <quantity>
}   

@Test (dependsOnMethods={"PlaceOrder"}, dataProvider = "dp")
public void ValidateSide(String username, String password, String product, String ordertype, String quantity, String side) {
    //check results <side>
}

@Test (dependsOnMethods={"PlaceOrder"}, dataProvider = "dp")
public void ValidateTotal(String username, String password, String product, String ordertype, String quantity, String side) {
    //check results - some calcs here
}

@AfterTest
public void CancelOrder() throws Exception {
    //Cancel the Order 
}   

}

The problem is when I run this - TestNG is passing all the data from each into each @Test method. I need it to pass each instance of through the sequence of methods.. so; , SignIn, SearchForProduct, PlaceOrder, ValidateQuantityAmount, ValidateSide, ValidateTotal, CancelOrder And then repeat this for the next instance of

Is my approach wrong? I understand each test need to be independent - but how can that be possible when runnin gend-to-end testing?

Thanks in advance

John

johnnyc007
  • 1
  • 1
  • 3
  • "TestNG is passing all the data from each into each @Test method" -- this is the designed behavior of data providers. To get the behavior that you desire, you will have to create a single test method that performs each of those steps in order. – Bob Dalgleish Jul 29 '14 at 12:22
  • So each current TestNG Test (sorry cant use the 'at' sign... ) would simply become a normal method - and these are then called from one TestNG Test ? The reporting for that would not be as great as it is for each TestNG Test. e.g. If the one TestNG Test failed on ValidateTotal for example, then the whole test would be marked as failed? – johnnyc007 Jul 29 '14 at 12:57
  • If I do not use the DataProvider, is there a way I can pass the object[][] test data through each TestNG Test ? – johnnyc007 Jul 29 '14 at 13:21

1 Answers1

0

Create your suite of tests, testng.xml:

<suite name="Johnny's Tests">
  <test name="pass1">
    <parameter name="username" value="letmein"/>
    ...
    <class name="PlaceOrderTestScript">
      <methods>
        <include name="*"/>
      </methods>
    </class>
  </test>
  <test name="pass2">
    ...
  </test>
  ,,, repeat for each test
</suite>

Then add your parameters to the test.

Bob Dalgleish
  • 8,167
  • 4
  • 32
  • 42