views:

198

answers:

3

I am attempting to write some test cases for some classes that involve testing the equality of two dimensional arrays of data. Here is my first stab at it:

double[][] expected = {
        {0, 104, 0},
        {145.5, 0, 0},
        {83, 0, 0}
};

double[][] actual = someObject.getArray();

Now, I see that JUnit does not have an 'arrayEquals' for double arrays, probably due to the floating point issue (you really want to use a delta vs equality). I notice that Junit-Addons has exactly the method I need to determine if they're equal:

static void  assertEquals(java.lang.String message, double[] expected, double[] actual, double delta)

Now, that's all well and fine. What I want to be able to do is give a meaningful error message, not just saying that the two are unequal but where they are unequal. Is there an easy way of doing this, short of comparing dimensions, then iterating over each corresponding element and testing for equality? It seems silly to have to do the same thing that's being done in the assertion, just to get a meaningful error message.

A: 

So, are you trying to compare double[]s or double[][]s?

If you are comparing double[]s (1D arrays), then yeah, how about using Junit-Addons? is its default error message not what you need? If you are able to write your tests to use Double[] instead, then JUnit's assertArraysEquals() method which operates on Object[] will work. It will compare doubles for exact equality though -- assuming that's what you intend.

If you're comparing double[][], then neither of these work. Even though double[][] is an Object[], you don't intend to compare individual double[]s since they just use reference equality.

You can use commons-lang to do the comparison, true, though it won't help you generate a useful message about where the difference is. For that, I think you need to roll your own method.

Sean Owen
A: 

I would think that you are conflating unit testing with instrumentation/debugging. The purpose of the unit test is to determine if your object works as expected. If you get into the habit of including code that is (effectively) instrumentation in your test cases, you increase the probability that you will write test cases that are designed to pass.

Your object has a method that is to return a double[][]. Your test case is telling you that it is not working as expected. Time to debug your code.

(I understand that this may be a controversial point of view.)

As far as I understand the question, I82Much wants to test equality of 2-dimensional arrays and a detailed error/fail message (like 'cell a12 expected value 104.0 but found value -104.0').
Andreas_D
Yes. My (potentially pedantic, possibly wise :) point is that, if his object had a method getCell(row, col), then identifying its failure for a given input would fall in the domain of testing. As it is, he is looking for his unit tests to do double duty as debuggers.
To clarify, assume returned array (n x m) has multiple errors. Adding a "feature" to the test framework that identifies the first case of failure tells you the first instance. Should it list all the instances of failure? What happens when you change the test data? Do you get a different set of failed cells? The test fails and it tells you what you need to know: you have a bug.
I guess I never thought that providing more data about a failure of a test is encroaching into the 'debugging' territory, but maybe you're right.
I82Much
A: 

Do I get it right, you're happy with the assertEquals(String, double[], double[], double) method from JUnit-Addons except for the output?

Assuming, you have or can get the source of the ArrayAssert class, just reimplement the method (copy&paste but check the license first) and enhance the outputs in the new custom assertEquals method to your needs. I think, it won't take too long!

Andreas_D