Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Should I expect the dataprovider to run 3x if there are 3 tests? #93

Closed
BrianJavaJazz opened this issue Mar 29, 2017 · 7 comments
Closed

Comments

@BrianJavaJazz
Copy link

I need to generate my data just once before 3 tests are run. Afterwards, I walk through the data and use each piece for the tests. For "this" entity type, test these things, then for the next entity type, test the same things, etc.

But as I increase the number of @Test-annotated tests which are run, the dataprovider will run additional times at startup. As it is getting the same data, this is unnecessary. It's possible I have this set up incorrectly.

Is this expected functionality? Is there a way to get the data a single time only?

I saw that issue #87 was similar, but not this exact issue.

Thank you!

Brian

JDK 1.8.0_121
JUnit 4.12.0
junit-dataprovider 1.12.0
eclipse STS 3.7.3

How about some code! Here is a simplified version of my test class and a secondary class which holds the data provider generator.

First, the test driver:

`
@RunWith(DataProviderRunner.class)
public class testdataprovider {

protected WebDriver driver;
protected NgWebDriver ngWebDriver;
public Map<String, String> createdDataMap;
public AddPageElements addPageElements;
public ListPageElements listPageElements;
private static boolean initialized = false;
public static LandingPageTestHandler testHandler;
public TestScriptHandler scriptHandler;
	
public static Object[][] actualData = null;

@DataProvider
public static Object[][] data() {		
	actualData = TestScriptHandler.getGenericsList(testHandler);
	return actualData;       
}


@Before
public void startup() {
	if (initialized == false) {
		scriptHandler = new TestScriptHandler();
		initialized = true;
	}
}

@Test
@UseDataProvider("data")
public void oOTestCreate(TypeDefinition typedef) {		
	System.out.println("\nTEST 1 " + typedef.getEntityType());
}


@Test
@UseDataProvider("data")
public void testUpdate(TypeDefinition typedef) {
	System.out.println("\nTEST 2  " + typedef.getEntityType());
}


@Test
@UseDataProvider("data")
public void testDeactivate(TypeDefinition typedef) {
	System.out.println("\nTEST 3 " + typedef.getEntityType());
}

}
`

Then, the secondary class which generates the Object[][]. This class logs in to an internal website, get a list of specific items, (the generic list, not a list of generics) then puts them into the typedefObjectArray. The array is then returned.

`public class TestScriptHandler {

public static Object[][] getGenericsList(LandingPageTestHandler testHandler) {
	
	BasePage basePage = new BasePage();
		LoginPage logginPage = basePage.getLoginPage();
	WebDriver driver = basePage.getDriver();
	NgWebDriver ngWebDriver = basePage.getNgWebDriver();

	logginPage.goTo()
	.loginAs(basePage.getUsername(), basePage.getPassword());

	testHandler = new LandingPageTestHandler(driver, ngWebDriver, basePage);
	ArrayList<TypeDefinition> genericList = testHandler.getGenericList();
	Object[][] typedefObjectArray = new Object[genericList.size()][1];
	
	for (int i=0; i < genericList.size();  i++) {
		typedefObjectArray[i][0] = (TypeDefinition)genericList.get(i);
	}
	driver.quit();
	return typedefObjectArray;		
}

}
`

@BrianJavaJazz
Copy link
Author

BrianJavaJazz commented Mar 29, 2017

Here is a simplified version of the code above. It will process just strings (so you can attempt locally).

`@RunWith(DataProviderRunner.class)
public class testdataprovider {
protected WebDriver driver;
protected NgWebDriver ngWebDriver;
public Map<String, String> createdDataMap;
public AddPageElements addPageElements;
public ListPageElements listPageElements;
private static boolean initialized = false;
public static LandingPageTestHandler testHandler;
public TestScriptHandler scriptHandler;

@DataProvider
public static Object[][] data() {		
	Object [][] actualData = (Object[][]) TestScriptHandler.getDataObject();
	return actualData;       		
}


@Before
public void startup() {
	System.out.println("startup in GenericTestDriverAutomated");
	if (initialized == false) {
		scriptHandler = new TestScriptHandler();
		initialized = true;
	}
}


@Test
@UseDataProvider("data")
public void oOTestCreate(String foo) {		
	System.out.println("\nTEST 1 " + foo);
}


@Test
@UseDataProvider("data")
public void testUpdate(String foo) {
	System.out.println("\nTEST 2  " + foo);
}


@Test
@UseDataProvider("data")
public void testDeactivate(String foo) {
	System.out.println("\nTEST 3 " + foo);
}

}`

The TestScriptHandler is an external class.

public class TestScriptHandler { public static Object getDataObject() { System.out.println("getting data object"); return new Object[][] { { "Entry One" }, { "Entry Two" }, { "Entry Three" }, }; } }

Stymied in Seattle.

@aaschmid
Copy link
Member

Hi @BrianJavaJazz, sorry but I am currently on a business trip and maintaining this in my spare time. I will have a look as soon as possible (at latest on the weekend).
Is that ok?

Cheers,
Andreas

@janschaefer
Copy link

Maybe I can try to answer the question. I think there is currently no way to tell the JUnitDataProvider runner to not call the data provider method each time. However, you can easily fix this yourself by just storing the results in a static variable and returning the variable once it has been generated. Like in your first example, where you even store the values in a static variable. You could modify that as follows:

 public static Object[][] actualData = null;

 @DataProvider
 public static Object[][] data() {		
        if (actualData != null) {
      	    actualData = TestScriptHandler.getGenericsList(testHandler);
        }
        return actualData;       
 }

@BrianJavaJazz
Copy link
Author

aaschmid and janschaefer,

Thank you both for your replies. janschaefer, that is pretty close to what I implemented just yesterday. In the external class which handles the data (where the dataprovider gets it's data) I have:

public static Object[][] preloadedData = null; ... if (preloadedData == null) { //go generate it }
In this scenario the data is generated once and returned as many times as needed without the extra logins and generation I had before. This shaved 15 seconds off of my testing! janschaefer, your solution is even better.

Thank you both. Cheers!

Brian

@aaschmid
Copy link
Member

aaschmid commented Apr 3, 2017

Hi @BrianJavaJazz,

you found an issue in the junit-dataprovider which needs to get fixed. Does the workaround provided by @janschaefer help so far. Unfortunately, I have no good idea for any better one ...

How urgent is it with the workaround in mind?

Cheers,
Andreas

@aaschmid aaschmid self-assigned this Apr 3, 2017
@aaschmid aaschmid added this to the next version milestone Apr 3, 2017
@BrianJavaJazz
Copy link
Author

Hello. Yes, the workaround is fine. I have no issues with it, and the urgency is no more than average. My main concern at the time was that a scan for the same data was costing my tests some extra time, but that was the only issue.

Thank you for your continued communication. I appreciate it.

Best regards,

Brian

aaschmid added a commit that referenced this issue May 7, 2017
in order to not call the same static dataprovider multiple times
aaschmid added a commit that referenced this issue May 7, 2017
in order to not call the same static dataprovider multiple times
@aaschmid
Copy link
Member

aaschmid commented Sep 25, 2017

Hi @BrianJavaJazz,

finally I released the new version v1.13.0 containing this fix.

Cheers,
Andreas

Edit: v1.13.1 contains the fix :-)

aaschmid added a commit that referenced this issue Oct 3, 2017
* issue93-cache-reused-dataprovider-results:
  cache and reuse dataprovider results (#93)
@aaschmid aaschmid reopened this Oct 3, 2017
@aaschmid aaschmid closed this as completed Oct 3, 2017
aaschmid added a commit that referenced this issue Oct 3, 2017
* issue93-cache-reused-dataprovider-results:
  cache and reuse dataprovider results (#93)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants