on Friday, July 9, 2010

I played around a bit with iteration using JUnit today. I have some generic tests that behave differently depending on the values fed to them. I don’t want to have iteration code living alongside each test (maintenance nightmare), so I wanted to use JUnit’s @Parameters tag to pull in my test data via a Preferences file and do the iteration for me.


It took me longer than I expected to get right, mostly because static methods annoy me and trip me up a bit. (Your parameters method must be static in order for it to work).


However, get it working I did. On the off chance that it saves someone else some time, here’s how it works:




import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Enumeration;
import java.util.Properties;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;

@RunWith(Parameterized.class)
public class paramTest
{
final static String dataFile = "/dataDriver.txt";
private String words;

public paramTest(String words)
{
this.words = words;
}

@Test
public void verifyThing() throws Exception
{
System.out.println("key: " + words);
}

@Parameters
public static Collection data()
{
Collection returnList = new ArrayList();
InputStream dataStream = paramTest.class.getResourceAsStream(paramTest.dataFile);
Properties dataProperties = new Properties();
try{
dataProperties.load(dataStream);
} catch(Exception e)
{ System.out.println(e);}

Enumeration e = dataProperties.propertyNames();
while (e.hasMoreElements())
{
returnList.add(new Object[]{dataProperties.getProperty((String) e.nextElement())});
}
return returnList;
}
}


Interestingly enough, the data comes back in the reverse order that it exists in the preferences file. Something to keep in mind if you want your tests to run in a certain order.