Dutch Ephemeris

Free astronomical software

Unit testing binary data

The Dutch Ephemeris uses a binary version of the VSOP data. The main advantage of binary data is the reduced footprint, the resulting binary data is typically three times smaller than the original textual data.

But how to test this?
To check the content of the data you need to have a reader and some interpretation logic. That would mean writing a lot of software before you write a test and that is not what you want.
I decided for a simple approach. After I write the file I compare the result with an existing reference file. Not byte-for-byte but using a checksum. The Adler-32 checksum is good enough for this approach, it is less strict than CRC-32 but it is also faster. And Adler-32 is conventently included in Java in the package java.util.zip.Adler32.

The test goes like this:

A jUnit class DataWriterTest is created to test DataWriter. In @BeforeClass an instance of DataWriter is created which takes care of creating the binary file.

Two additional methods are added to the jUnit class. The first one is
private static byt[] readBytesFromFile(File someFile)
This method returns an array of bytes as read from the file and is pretty much straightfroward.

The second method performs the checksum using the Adler-32 algorithm.

private static int adlerChecksum( byte[] theTextToDigestAsBytes ) {
 Adler32 adler = new Adler32();
 adler.update( theTextToDigestAsBytes );
 return (int) adler.getValue();
}

The test itself

@Test
public void testAdlerChecksum4File() {
  // userDir is defined globally using private static String userDir = System.getProperty("user.dir");
  String referencePath = userDir + File.separator + "files4jUnitArchived" + File.separator + "testdata.bin";
  File referenceFile = new File(referencePath);
  byte[] refBytes = null;
  byte[] actBytes = null;
  try {
     refBytes = readBytesFromFile(referenceFile);
     actBytes = readBytesFromFile(targetFile); // defined in @beforeClass
  } catch (IOException e) {
     fail("IOException :" + e.getMessage());
  }
  int adlerValue4Ref = adlerChecksum(refBytes);
  int actValue4Ref = adlerChecksum(actBytes);
  assertTrue(adlerValue4Ref == actValue4Ref);
}

Chicken or egg?

To have a reference file you need to create one first. I did this using the same software as I am testing with this unit test. Obviously this test does not tell me very much about the correctness of the created file. But it does make it possible to find newly introduced errors which would result in a different binary file. And as soon as the software that uses the binary data is ready I can be sure about its content. And the tests will already be in place.