I’m looking for direction on how to test that a dynamically generated image is the expected image with JUnit. A bit of background:
I have code that generates thumbnail images as java.awt.image.BufferedImage’s and stores those BufferedImages into a java.io.File object.
I wrote a simple unit test to check a few key items in order to gain confidence that the generated image was correct:
@Test public void testGenerateDefaultThumbnail() { File file = // someGeneratedFile.jpg assertNotNull(file); assertEquals(10211l, file.length()); }
Basically, I’m just confirming that the file size is what I expect.
This works fine locally on my machine (Mac OSX), but as soon as our tests run on our build server (Ubuntu), one of the tests is failing with the following:
java.lang.AssertionError: expected:<10211> but was:<10158> at org.junit.Assert.fail(Assert.java:88) at org.junit.Assert.failNotEquals(Assert.java:743) at org.junit.Assert.assertEquals(Assert.java:118) at org.junit.Assert.assertEquals(Assert.java:555) at org.junit.Assert.assertEquals(Assert.java:542) at c.v.t.ThumbnailTest.testGenerateDefaultThumbnail(ThumbnailTest.java:53)
Three part question:
- Why may the file size be different for an image across OS’s?
- Is there a standard approach to unit testing image generation?
- Should I change my approach to compare two File objects (where a pre-generated file exists as a resource in the project)?
Thanks!
Advertisement
Answer
I would guess there’s a difference in the metadata being written out? The image data is probably the same. If you only care about the image data and not the metadata for the image file you can just pull out the pixel data as a byte array.
this is probably a good idea anyway since comparing the entire file will be problematic since the metadata may have timestamps of the file generation which will break the tests.
If you already have the image as a BufferedImage
you can just do this on the expected
and actual
variables.
//this gets the actual Raster data as a byte array byte[] byteArray = ((DataBufferByte) bufferedImage.getData().getDataBuffer()).getData();
Then just compare the byte arrays for equality
assertArrayEqual(expectedArray, actualArray);
If you don’t have the data as a bufferedImage yet it’s easy to get it from a file
BufferedImage originalImage = ImageIO.read(new File("path/to/my.jpg"));
or InputStream
try{ BufferedImage originalImage = ImageIO.read(inputStream)); }finally{ //close inputstream inputStream.close(); }