1

I am beginning with Java and testng test cases.

I need to write a class, which reads data from a file and makes an in-memory data structure and uses this data structure for further processing. I would like to test, if this DS is being populated correctly. This would call for dumping the DS into a file and then comparing the input file with the dumped file. Is there any testNG assert available for file matching? Is this a common practice?

xyz
  • 8,607
  • 16
  • 66
  • 90

5 Answers5

3

I think it would be better to compare the data itself not the written out data.

So I would write a method in the class to return this data structure (let's call it getDataStructure()) and then write a unit test to compare with the correct data.

This only needs a correct equals() method in your data structure class and do:

Assert.assertEquals(yourClass.getDataStructure(), correctData);

Of course if you need to write out the data structure to a file, then you can test the serialization and deserialization separately.

KARASZI István
  • 30,900
  • 8
  • 101
  • 128
1

File compare/matching can be extracted to a utility method or something like that. If you need it only for testing there are addons for jUnit http://junit-addons.sourceforge.net/junitx/framework/FileAssert.html

If you need file compare outside the testing environment you can use this simple function

    public static boolean fileContentEquals(String filePathA, String filePathB) throws Exception {
    if (!compareFilesLength(filePathA, filePathB)) return false;

    BufferedInputStream streamA = null;
    BufferedInputStream streamB = null;
    try {
        File fileA = new File(filePathA);
        File fileB = new File(filePathB);

        streamA = new BufferedInputStream(new FileInputStream(fileA));
        streamB = new BufferedInputStream(new FileInputStream(fileB));

        int chunkSizeInBytes = 16384;
        byte[] bufferA = new byte[chunkSizeInBytes];
        byte[] bufferB = new byte[chunkSizeInBytes];

        int totalReadBytes = 0;
        while (totalReadBytes < fileA.length()) {
            int readBytes = streamA.read(bufferA);
            streamB.read(bufferB);

            if (readBytes == 0) break;

            MessageDigest digestA = MessageDigest.getInstance(CHECKSUM_ALGORITHM);
            MessageDigest digestB = MessageDigest.getInstance(CHECKSUM_ALGORITHM);

            digestA.update(bufferA, 0, readBytes);
            digestB.update(bufferB, 0, readBytes);

            if (!MessageDigest.isEqual(digestA.digest(), digestB.digest()))
            {
                closeStreams(streamA, streamB);
                return false;
            }

            totalReadBytes += readBytes;
        }
        closeStreams(streamA, streamB);
        return true;
    } finally {
        closeStreams(streamA, streamB);
    }
}

public static void closeStreams(Closeable ...streams) {
    for (int i = 0; i < streams.length; i++) {
        Closeable stream = streams[i];
        closeStream(stream);
    }
}
public static boolean compareFilesLength(String filePathA, String filePathB) {
    File fileA = new File(filePathA);
    File fileB = new File(filePathB);

    return fileA.length() == fileB.length();
}
private static void closeStream(Closeable stream) {
    try {
        stream.close();
    } catch (IOException e) {
        // ignore exception
    }
}

Your choice, but having an utility class with that functionality that can be reused is better imho.

Good luck and have fun.

Ivan Raykov
  • 141
  • 4
0

Personally I would do the opposite. Surely you need a way to compare two of these data structure in the Java world - so the test would read from the file, build the DS, do its processing, and then assert it's equal to an "expected" DS you set up in your test.

(using JUnit4)

@Test
public void testProcessingDoesWhatItShould() {
    final DataStructure original = readFromFile(filename);
    final DataStructure actual = doTheProcessingYouNeedToDo(original);
    final DataStructure expected = generateMyExpectedResult();

    Assert.assertEquals("data structure", expected, actual);
}
Guillaume
  • 22,694
  • 14
  • 56
  • 70
0

If this DS is a simple Java Bean. then you can use EqualsBuilder from Apache Commons to compare 2 objects.

Andrey Adamovich
  • 20,285
  • 14
  • 94
  • 132
0

compare bytes loaded from file system and bytes you are going to write file system

pseudo code

byte[]  loadedBytes = loadFileContentFromFile(file) // maybe apache commons IOUtils.toByteArray(InputStream input) 

byte[]  writeBytes = constructBytesFromDataStructure(dataStructure)

Assert.assertTrue(java.util.Arrays.equals(writeBytes ,loadedBytes));
swanliu
  • 781
  • 3
  • 8