DataProvider returns undefined Object?

83 views
Skip to first unread message

DeeOohEhm

unread,
Sep 28, 2016, 11:24:11 PM9/28/16
to testng-users
Hi all,

To start off I have a data model class that is inherited by two data provoking classes. These classes are lets say DataModelA and DataModelB. All these classes do is read from a specified JSON file and have getters and setters for these values. I have two test classes that want to use the same data provider.

For Example:


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

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


I'm trying to figure out how to model this data provider.

So far I can have the data provider return just a single class, but I need this to be dynamic. This is what it looks like now.


@DataProvider(name = "JsonDataProvider")
protected static Object[][] getJsonDataModel() {
return new Object[][]{ { new DataModelA() } };
}


This will work for DataModelA, but not DataModelB. How can I make this dynamic?


Thanks in advance. 

Dominic


⇜Krishnan Mahadevan⇝

unread,
Sep 29, 2016, 11:04:03 AM9/29/16
to testng...@googlegroups.com
Dominic,

Why not do something like this ?
  • Define a common marker interface that your data models will implement. [ This is just optional because your data provider always returns back only an Object and that can be assigned to anything ]
  • Define your test methods to accept parameters of your marker type interfaces within your test class have them casted over to your actual data model type. 
  • Pass in an indicator via your suite xml file to your data provider so that it knows what type of data to instantiate.
public class UbiquitousDataProviderSample {

@Test(dataProvider = "dp", groups = "students")
public void testStudents(CommonData data) {
Assert.assertTrue(data instanceof Student);
}

@Test(dataProvider = "dp", groups = "runner")
public void testRunnerNames(CommonData data) {
Assert.assertTrue(data instanceof TestRunner);
}

@DataProvider(name = "dp")
public Object[][] getData(ITestContext context) {
String testName = context.getCurrentXmlTest().getName();
String type = context.getCurrentXmlTest().getParameter("type");
System.err.println(testName + " passed " + type + " as the type .");
Object[][] object = null;
switch (type) {
case "student":
object = new Object[][] {
{new Student("Jack", 10)},
{new Student("Jill", 12)}
};
break;
case "runner":
object = new Object[][] {
{new TestRunner("TestNG")},
{new TestRunner("JUnit")}
};
}
return object;
}

/**
* Marker interface just to establish commonality
*/
interface CommonData {}

public static class Student implements CommonData {
private String name;
private int age;

public Student(String name, int age) {
this.name = name;
this.age = age;
}

public String getName() {
return name;
}

public int getAge() {
return age;
}
}


public static class TestRunner implements CommonData {
private String runnerName;

public TestRunner(String runnerName) {
this.runnerName = runnerName;
}

public String getRunnerName() {
return runnerName;
}
}
}

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Ubiquity-suite" verbose="2">
<test name="ubiquity-test1">
<parameter name="type" value="student"/>
<groups>
<run>
<include name="students"/>
</run>
</groups>
<classes>
<class name="organized.chaos.testng.UbiquitousDataProviderSample"/>
</classes>
</test>
<test name="ubiquity-test2">
<parameter name="type" value="runner"/>
<groups>
<run>
<include name="runner"/>
</run>
</groups>

<classes>
<class name="organized.chaos.testng.UbiquitousDataProviderSample"/>
</classes>
</test>
</suite>






Thanks & Regards
Krishnan Mahadevan

"All the desirable things in life are either illegal, expensive, fattening or in love with someone else!"
My Scribblings @ http://wakened-cognition.blogspot.com/
My Technical Scribbings @ http://rationaleemotions.wordpress.com/

--
You received this message because you are subscribed to the Google Groups "testng-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to testng-users+unsubscribe@googlegroups.com.
To post to this group, send email to testng...@googlegroups.com.
Visit this group at https://groups.google.com/group/testng-users.
For more options, visit https://groups.google.com/d/optout.

Julien Herr

unread,
Sep 29, 2016, 11:45:04 AM9/29/16
to testng-users
A solution could be to inject the Method in the data provider method (http://testng.org/doc/documentation-main.html#native-dependency-injection)

and then you can return the appropriate object depending on the method (and maybe its params).

DeeOohEhm

unread,
Oct 3, 2016, 6:32:08 PM10/3/16
to testng-users
I'm still having trouble with this. Data injection sounds neat, but the example on TestNG documentation isn't very helpful.... Again, I'm trying to take the parameter from the test method and return that as an object from the DataProvider method itself. I don't want to have to write new code everytime I create a new data model.

Thanks,

Dominic

⇜Krishnan Mahadevan⇝

unread,
Oct 3, 2016, 11:51:48 PM10/3/16
to testng...@googlegroups.com
Dominic,

Did you try executing the sample I shared ? If you followed the sample that I shared, then you don't need to do anything apart from the following whenever there is a new data model you introduce.

  1. Add a new @Test method for dealing with the new data model but which will continue to accept the same marker interface type as its parameter.
  2. Add new code to your @DataProvider method so that it knows how to produce data objects for your new data model.
You cannot get away without writing new code whenever you add a new data model because your @DataProvider still needs to know how to create your new data model instances and return them back to your @Test method.

Thanks & Regards
Krishnan Mahadevan

"All the desirable things in life are either illegal, expensive, fattening or in love with someone else!"
My Scribblings @ http://wakened-cognition.blogspot.com/
My Technical Scribbings @ http://rationaleemotions.wordpress.com/

Reply all
Reply to author
Forward
0 new messages