0

So to start off, I am building out an automation library built on top of Selenium and Java. I'm building out a way to parameterize data that is being passed into test methods. I am using TestNG.

Right now I have two sample Test methods that take in different Data Models as a parameter. For example, testOne takes in TestModelA, and testTwo takes in TestModelB. However, both of these use the SAME dataProvider. These TestModel classes read from a JSON file and returns the data in getter methods.

Example:

@Test(dataProvider = "JsonDataProvider")
public void testDataProviderOne(TestModelA testData) {
    System.out.println(testData.getTestDataAA());
    System.out.println(testData.getTestDataAB());
}

@Test(dataProvider = "JsonDataProvider")
public void testDataProviderTwo(TestModelB testData) {
    System.out.println(testData.getTestDataBA());
    System.out.println(testData.getTestDataBB());
}

What I need help with is building out this DataProvider method...

Right now it will work with one of them if I return the specified Class.

Example:

@DataProvider(name = "JsonDataProvider")
protected static Object[][] getJsonDataModel() {

    return new Object[][]{ { new TestModelA() } };
}

I need the DataProvider to return whichever Object is being passed into the test method as a parameter that is using this data provider.

What is the best way to accomplish this.

If you want to check out my project on GitHub, you can at: https://github.com/Dominic-Pace/AutoCoreCommons

dpace
  • 21
  • 1
  • 7

2 Answers2

1

To make things cleaner I suggest to have separate data providers. So It would be easy to understand and easy to maintain.

Yes if you want to externalize the data provider methods in separate file. That can be achieved.

What you need to do for that:

  1. Create a data provider class.
  2. Put all your data provider methods in this class.
  3. All data provider method should be public and static.
  4. Call your test specific data provider in your @Test methods.

Here is how it will look like in your case:

The MyDataProvider.java class

package example.dataprovider;

import org.testng.annotations.DataProvider;

public class MyDataProvider {
    @DataProvider(name = "JsonDataProviderForTestModelA")
    public static Object[][] getJsonDataProviderForTestModelA() {

        return new Object[][]{ { new TestModelA() } };
    }

    @DataProvider(name = "JsonDataProviderForTestModelB")
    public static Object[][] getJsonDataProviderForTestModelB() {

        return new Object[][]{ { new TestModelB() } };
    }
}

Your @Test methods can use data provider specific to it's requirement. Like

@Test(dataProvider = "JsonDataProviderForTestModelA")
public void testDataProviderOne(TestModelA testData) {
    System.out.println(testData.getTestDataAA());
    System.out.println(testData.getTestDataAB());
}

@Test(dataProvider = "JsonDataProviderForTestModelB")
public void testDataProviderTwo(TestModelB testData) {
    System.out.println(testData.getTestDataBA());
    System.out.println(testData.getTestDataBB());
}
FayazMd
  • 386
  • 2
  • 22
Atul Dwivedi
  • 1,452
  • 16
  • 29
  • I could do this, but when I get into 1500 - 2000 different test cases that use different data sets it gets to be a lot. I'm looking for some kind of factory to return an instance of a class or something. Thanks anyways though! – dpace Oct 03 '16 at 22:01
0

DataProvider is providing Object as a return type, which means you can type cast to the type your test method is returning.

However, your example shows, you have two methods which is doing the exact same thing, except the fact that, it is taking different classes as an argument, then I would like to suggest, use a super class to your TestModelA and TestModelB classes and then in your super class, put the method testDataProvider(SuperClass sc) which accepts this super class as an argument then call this method by passing any sub type.

Atul Dwivedi
  • 1,452
  • 16
  • 29
FayazMd
  • 386
  • 2
  • 22