Last week I ran into an issue passing a lazy dataprovider to a factory. The following is the issue I first ran into:
The issue I was having is that when I ran my class it ran X (# of .xml files) number of tests using the last value contained in the array.
So if I had [“Oregon.xml”, “NewYork.xml”, “Washingtion.xml”] Washington will run 3 times.
class supplyData{ @DataProvider public static Iterator<Object[]> loadStatePages(){ List<Object[]> allParsedXMLPages = new ArrayList<Object[]>() int loadNextState = 0 //create array containing x "StatePage.xml"; where x = # of states def allStatePages = getCityStatePages("State") allStatePages.each {singleStatePage -> def loadedStatePage = loadFile(singleStatePage) //create array containing [0]STATENAME, [2]ABBREVNAME, [3]ARRAY CITYNAMES def allStates = getStateContainer() //load next state to load into currentState def currentState = allStates[loadNextState] def fullStateName = currentState[0].toString() def abbrevState = currentState[1].toString() //create allCities by remove the fullStateName and abbrevState from array def allCities = currentState allCities.remove(0) allCities.remove(0) def cityLink = "" for (city in allCities) { def cityHref = city.text().replaceAll(/\W+/, '-') cityLink = cityLink +('<link>\n' + '<title>'+ city + '</title>\n' + '<linktext>' + city + '</linktext>\n' + '<asserthref>/' + cityHref.toLowerCase() + '</asserthref>\n' + '<asserttitle>' + city + ", " + fullStateName + '</asserttitle>\n' + '</link>\n' ) } String bodyStatePage = loadedStatePage.getText() ++loadNextState def parsedStatePage = parseString(bodyStatePage) def completeStatePage = createFullXMLPage(bodyStatePage, parsedStatePage) //add the parsed page to our ArrayList allParsedXMLPages.add(completeStatePage as Object[]) } return allParsedXMLPages.iterator() } }
public class CityTests{ static cityCurrentXML public CityTests(newXML){ this.cityCurrentXML = newXML } @Factory (dataProviderClass=supplyData.class, dataProvider="loadCityPages") public static Object[] getNextXML(cityCurrentXML){ return [new CityTests(cityCurrentXML)] } @BeforeClass void openBrowser(){ startBrowser() } @Test (description="Check MetaTags for correct content") public void MetaTags(){ def errors = testMetaTags(cityCurrentXML) assertPageTest(errors, cityCurrentXML.PAGENAME.text()) } @Test (description="Check Links for existance, clickability, and target") public void Links(){ def errors = testLinks(cityCurrentXML) assertPageTest(errors, cityCurrentXML.PAGENAME.text()) } @Test (description="Check Text for existance and accuracy") public void Text(){ def errors = testText(cityCurrentXML) assertPageTest(errors, cityCurrentXML.PAGENAME.text()) } @Test (description="Check Overlays for existance, links, and text") public void Overlays(){ def errors = testOverlays(cityCurrentXML) assertPageTest(errors, cityCurrentXML.PAGENAME.text()) } @Test (description="Check Hovers for existance, links, and text") public void Hovers(){ def errors = testHovers(cityCurrentXML) assertPageTest(errors, cityCurrentXML.PAGENAME.text()) } @Test (description="Check Inputs for existance, typeability, and target") public void Inputs(){ def errors = testInputs(cityCurrentXML) assertPageTest(errors, cityCurrentXML.PAGENAME.text()) } @Test (description="Check Sliders for existance, links, and text") public void Sliders(){ def errors = testSliders(cityCurrentXML) assertPageTest(errors, cityCurrentXML.PAGENAME.text()) } @Test (description="Check Images for existance and display") public void Images(){ def errors = testImgLoaded(cityCurrentXML) assertPageTest(errors, cityCurrentXML.PAGENAME.text()) } @Test (description="Check AtlasTags for existance and value") public void AtlasTags(){ def errors = testAtlas(cityCurrentXML) assertPageTest(errors, cityCurrentXML.PAGENAME.text()) } @AfterClass void tearDown(){ driver.quit() } }
To fix this issue I had to make the following changes:
class supplyData{
class supplyData{ @DataProvider public static Object[][] loadStatePages(){ List<Object[]> allParsedXMLPages = new ArrayList<Object[]>() int loadNextState = 0 //create array containing x "StatePage.xml"; where x = # of states def allStatePages = getCityStatePages("State") allStatePages.each {singleStatePage -> def loadedStatePage = loadFile(singleStatePage) //create array containing [0]STATENAME, [2]ABBREVNAME, [3]ARRAY CITYNAMES def allStates = getStateContainer() //load next state to load into currentState def currentState = allStates[loadNextState] def fullStateName = currentState[0].toString() def abbrevState = currentState[1].toString() //create allCities by remove the fullStateName and abbrevState from array def allCities = currentState allCities.remove(0) allCities.remove(0) def cityLink = "" for (city in allCities) { def cityHref = city.text().replaceAll(/\W+/, '-') cityLink = cityLink +('<link>\n' + '<title>'+ city + '</title>\n' + '<linktext>' + city + '</linktext>\n' + '<asserthref>/' + cityHref.toLowerCase() + '</asserthref>\n' + '<asserttitle>' + city + ", " + fullStateName + '</asserttitle>\n' + '</link>\n' ) } String bodyStatePage = loadedStatePage.getText() ++loadNextState def parsedStatePage = parseString(bodyStatePage) def completeStatePage = createFullXMLPage(bodyStatePage, parsedStatePage) //add the parsed page to our ArrayList allParsedXMLPages.add(completeStatePage as Object) } return allParsedXMLPages } }
public class CityTests{ private cityCurrentXML public CityTests(newXML){ this.cityCurrentXML = newXML } @Factory (dataProviderClass=supplyData.class, dataProvider="loadCityPages") public static Object[] getNextXML(cityCurrentXML){ return [new CityTests(cityCurrentXML)] } @BeforeClass void openBrowser(){ startBrowser() } @Test (description="Check MetaTags for correct content") public void MetaTags(){ def errors = testMetaTags(cityCurrentXML) assertPageTest(errors, cityCurrentXML.PAGENAME.text()) } @Test (description="Check Links for existance, clickability, and target") public void Links(){ def errors = testLinks(cityCurrentXML) assertPageTest(errors, cityCurrentXML.PAGENAME.text()) } @Test (description="Check Text for existance and accuracy") public void Text(){ def errors = testText(cityCurrentXML) assertPageTest(errors, cityCurrentXML.PAGENAME.text()) } @Test (description="Check Overlays for existance, links, and text") public void Overlays(){ def errors = testOverlays(cityCurrentXML) assertPageTest(errors, cityCurrentXML.PAGENAME.text()) } @Test (description="Check Hovers for existance, links, and text") public void Hovers(){ def errors = testHovers(cityCurrentXML) assertPageTest(errors, cityCurrentXML.PAGENAME.text()) } @Test (description="Check Inputs for existance, typeability, and target") public void Inputs(){ def errors = testInputs(cityCurrentXML) assertPageTest(errors, cityCurrentXML.PAGENAME.text()) } @Test (description="Check Sliders for existance, links, and text") public void Sliders(){ def errors = testSliders(cityCurrentXML) assertPageTest(errors, cityCurrentXML.PAGENAME.text()) } @Test (description="Check Images for existance and display") public void Images(){ def errors = testImgLoaded(cityCurrentXML) assertPageTest(errors, cityCurrentXML.PAGENAME.text()) } @Test (description="Check AtlasTags for existance and value") public void AtlasTags(){ def errors = testAtlas(cityCurrentXML) assertPageTest(errors, cityCurrentXML.PAGENAME.text()) } @AfterClass void tearDown(){ driver.quit() } }
As you can see I removed the lazy dataProvider as I was unable to pass the object correctly to the factory. The main issue I had was when passing the object to a static variable the factory recreate the class with the last loaded static value. Hope this helps you get a dataProvider with factory working correctly for you!
Justin