DataProviders for TestNG tests

Published by

on

When you need to run the same test a number of times, by changing only a few variable values, instead of writing several identical tests, you can use the dataProvider functionality offered by TestNG. What you have to do is declare a dataProvider method that returns a list of lists of objects, pass it to the test method, change the test method’s signature to correspond to the types of objects found in each inner list and run the test.

The first thing you need to do is declare the dataProvider, which is actually a method. You can do this either directly in the class where the test that will use it is placed, or in a different class. A typical dataProvider would look like this:

@DataProvider(name = "aDataProvider")
public static Object[][] aDataProvider() {
return new Object[][]{
     {Object1, Object2,... ObjectN},
     {Object1', Object2',...,ObjectN'},
     ...};
}


The dataProvider method will return an Object[][] (a list of lists of objects). Here, the size of the external list (the list of lists) will correspond to the number of runs that the method that uses the dataProvider will execute. The size of the inner lists will correspond to the number of parameters that will be passed into the test method at each execution. Let’s take the first list of the external list. It has n objects. This means that the test method’s signature will consist of n parameters of the types that correspond to the objects. Note that each object in the list can be of different types (you can have a mix of primitives with regular objects). The only thing to make sure of is that each list within the external list has the same size, to comply with the method’s signature. In case of a mismatch in the number of parameters the test method requires and the number of parameters fed into it by the dataProvider, an exception will be thrown.
If the dataProvider declares a number of parameters, and the test method declares a lower number, the following exception will be thrown (here, instead of 2 provided parameters, the test method only expected 1):

org.testng.TestNGException:
The data provider is trying to pass 2 parameters but the method acceptance.package1.tests.WithDataProviderTest#testWithDataProvider takes 1


If it is the other way around, the following similar exception is thrown:

org.testng.TestNGException:
The data provider is trying to pass 2 parameters but the method acceptance.package1.tests.WithDataProviderTest#testWithDataProvider takes 3 and TestNG is unable in inject a suitable object


Making the test class use the dataProvider is exemplified below (for the situation when the dataProvider and test method are found within the same class):

@Test(dataProvider = "aDataProvider")
public void testWithDataProvider(String text, int number) {
      System.out.println("text = " + text);
      System.out.println("number = " + number);
}

@DataProvider(name = "aDataProvider")
public static Object[][] aDataProvider() {
return new Object[][]{
      {"test", 100},
      {"secondTest", 200},
      {"thirdTest", 300}

};
}
;


Here, in the @Test annotation of the test method, you only need to declare ‘dataProvider = nameOfTheDataProvider’, as it appears in its’ @DataProvider definition. If the dataProvider is found in another class, the @Test annotation needs to also receive the ‘dataProviderClass = className.class’, where ‘className’ is the class where the dataProvider is declared.
When running the test from an IDE you will see in the run list, next to the name of the method, the values of the parameters that were used in the execution of the method. Note that for each run of the method, one of the lists of the external list will feed values into the parameters from the test’s signature (the lists do not get mixed up with each other). In the example above, the test runs 3 times, for each run printing the value of a String and the value of an int parameter.
Also, note that only methods annotated with @Test allow for the use of dataProviders. Methods annotated with @BeforeClass, @BeforeMethod, @AfterClass or @AfterMethod do not allow this functionality.

6 responses to “DataProviders for TestNG tests”

  1. arena Avatar
    arena

    Hi!

    Is it possible to filtering dataprovider? Meaning, my dataprovider object has 4 test dataset (id, name, email). I store all of my test data in the Dataprovider but for one particular test cases I want to run only 1 dataset, where id is 1. is it possible? Thanks!

    Like

    1. iamalittletester Avatar
      iamalittletester

      Hello.
      Well for this case, inside the test you can do something like (assuming the id is an int):
      if (id==1) {….all the test code here…}; – in this case all the test steps only run if the id is 1, and if it is not, no code gets executed and the test will finish successfully for all the entries from the data provider that were not used. So if the data provider has 5 entries, you will have 5 test runs, but only one will actually do anything.
      If you want to do it differently, you could throw a SkipException for all those entries for which you don’t want to run the test. That will look like:
      if (id1) throw new SkipException;
      ….all the test code here….
      This says, that if the id is anything but 1, a SkipException will be thrown, and in the test run report you will see the test run for those entries as skipped. The test with id 1 will run normally.
      Hope this helps.

      Like

  2. Nigonda Avatar
    Nigonda

    catch (final IMSConnectorException e)
    {

    if (e.getHttpStatusCode() == Response.Status.UNAUTHORIZED.getStatusCode())
    {
    throw new IMSException(Response.Status.UNAUTHORIZED, ErrorMessage.IMS_ACCESS_DENIED);
    }
    else
    {
    LOGGER.error(ErrorMessage.IMS_EXCEPTION + ” ” + e.getMessage()
    + ” [STACK TRACE] ” + Arrays.asList(e.getStackTrace()));
    throw new IMSException(Response.Status.INTERNAL_SERVER_ERROR, ErrorMessage.IMS_ERROR);
    }
    }

    /*…How i can write test cases for these Exception using DataProvider.
    please help

    Like

    1. iamalittletester Avatar
      iamalittletester

      Can you please explain what variables you want to put into the data provider out of this code? So i understand the use case.

      Like

      1. Nigonda Avatar
        Nigonda

        i got solution for this

        Like

      2. Nigonda Avatar
        Nigonda

        thank u

        Like

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Blog at WordPress.com.