JUnit: A Little Beyond @Test, @Before, @After
Consider my jrawio project: it's a decoder for different image file formats, so the integration tests match the same scheme: get a file, read and extract some information from it, assert expected results (as a marginal note for understanding the following examples, to assert that I'm reading the expected raster, which is made by many millions of pixels, I'm computing its MD5 and checking against it).
This is a sketch from a decoder test as it was at the beginning of this month:
public class NEFImageReaderTest
{
@Test(timeout=60000)
public void testJRW146()
throws Exception
{
final String path = "https://imaging.dev.java.net/nonav/TestSets/fabriziogiudici/Nikon/D100/NEF/NikonCaptureEditor/ccw90.nef";
final ImageReader ir = getImageReader(path);
assertEquals(1, ir.getNumImages(false));
assertEquals(1, ir.getNumThumbnails(0));
assertImage(ir, 3034, 2024);
assertThumbnail(ir, 0, 120, 160);
final BufferedImage image = assertLoadImage(ir, 3034, 2024, 3, 16);
assertLoadThumbnail(ir, 0, 120, 160);
close(ir);
assertRaster(image, path, "3659664029723dc8ea29b09a923fca7d");
}
@Test(timeout=60000)
public void testJRW148()
throws Exception
{
final String path = "https://imaging.dev.java.net/nonav/TestSets/fabriziogiudici/Nikon/D100/TIFF/TIFF-Large.TIF";
final ImageReader ir = getImageReader(path);
assertEquals(1, ir.getNumImages(false));
assertEquals(1, ir.getNumThumbnails(0));
assertImage(ir, 3008, 2000);
assertThumbnail(ir, 0, 160, 120);
final BufferedImage image = assertLoadImage(ir, 3008, 2000, 3, 16);
assertLoadThumbnail(ir, 0, 160, 120);
close(ir);
assertRaster(image, path, "03383e837402452f7dc553422299f057");
}
...
}
Pretty much copy & paste, isn't it? Figure out that I've got dozens of test files, more will be added, and a lot of metadata items must be tested too. This isn't going to scale a lot.
- Login or register to post comments
- 9328 reads
- Printer-friendly version
(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)










Comments
gjeudy replied on Wed, 2009/08/26 - 12:41pm
Fabrizio,
Have you tried testNG? It has a similar feature and seems easier to use than the example you posted here.
See @DataProvider annotation. The test runs also display much nicer in eclipse IDE than what you posted in this article. It shows the test method with arguments passed.
More over it has multi-threaded testing support though I haven't tried @DataProvider option combined with multi-threaded testing.
anewhope replied on Wed, 2009/08/26 - 8:43pm
@Fabrizio
One thing to note is that @RunWith is experimental in JUnit. I just checked the latest version of JUnit (4.7) and the javadoc is consistent with the following link:
http://junit.sourceforge.net/javadoc/org/junit/runner/RunWith.html
"...We added this feature late in development. While it seems powerful we expect the runner API to change as we learn how people really use it. Some of the classes that are currently internal will likely be refined and become public."
So I wouldn't rely on this for a large amount of testing. Also, the explanation of how JUnit finds constructors based on the number of arguments doesn't appear to be correct. I think a JUnit expects there to be only one constructor otherwise you'll get a "Testcase: initializationError" at least in JUnit 4 (standard in Netbeans 6.7.1).
I like your modification to Parameterized and hope they accept the changes.
Casper Bang replied on Thu, 2009/08/27 - 6:04am
Hmm, could one not also write a generator extension that hooks in front of JUnit's preprocessor? Then something like this would be possible:
@interface JUnitGenerator{
// Marker
}
At compile time, let a simple AnnotationProcessor (recognizing the marker interface JUnitGenerator) generate the @Test methods via TreeTranslator. JUnit will see things as if you handcoded each and every test method.
I realize code generation is a touchy issue, but I always found it handy for testing (although admitedly I've never done it exactly like this).
Ignacio Coloma replied on Thu, 2009/08/27 - 3:01am
in response to: anewhope
kackboy replied on Fri, 2009/08/28 - 3:59am
in response to: icoloma
Fabrizio Giudici replied on Fri, 2009/08/28 - 8:53am
in response to: kackboy
@anewhope. Yes, I know this thing is not part of a stable API. But it would not be hard to apply changes after JUnit eventually changes the API.
@casperbang. Very nice suggestion! No, I don't get worried by code generators :-) indeed there are already a couple in jrawio. Your suggestion sounds as a nice alternative to Groovy - indeed this brings me to a recurrent thought, that every time I think Groovy is useful for a problem, I later found (or somebody later suggests) an equivalent way to do things with Java ;-)
petersellars replied on Sun, 2009/10/11 - 2:15am
in response to: fabriziogiudici
Hi Fabrizio - did you submit a patch for this? Was it accepted or rejected? It seems useful to have a name for reference rather than just an index? Something like this could be an extended Parameterized class - such as IdentifedParamerterizedClass.
Am curious as I am going to use your patch for an upcoming presentation on this feature of JUnit. Will acknowledge you in my presentation and link to this page. Am also going to look at using a file/or group of files to contain the test data.
sunrise1 replied on Mon, 2009/10/26 - 3:27am