Monday, 14 December 2015

One liner JUnit Productivity Tip

There's nothing clever or complicated about this tip - nevertheless it's one that once discovered saved me a lot of time.

The tip is for the case when you're comparing two long strings.

Say you have the following code which compares two strings:

String expect = "a,aah,aahed,aahing,aahs,aardvark,aardvarks,aardwolf,ab,abaci,aback,abacus,abacuses,abaft,abalone,abalones,abandon,abandoned,abandonedly,abandonee,abandoner,abandoners,abandoning,abandonment,abandonments,abandons,abase,abased,abasedly,abasement,abaser,abasers,abases,abash,abashed,abashedly,abashes,abashing,abashment,abashments,abasing,abatable,abate,abated,abatement,abatements,abater,abaters,abates,abating,abatis,abatises,abator,abattoir,abattoirs,abbacies,abbacy,abbatial,abbe,abbes,abbess,abbesses";
String actual = "a,aah,aahed,aahing,aahs,aardvark,aardvarks,aardwolf,ab,abaci,aback,abacus,abacuses,abaft,abalone,abalones,abandon,abandoned,abandonedly,abandonee,abandoner,abandoners,abandoning,abandonment,abandonments,abandons,abase,abased,abasedly,abasement,abaser,abasers,abases,abash,abashed,abashedly,abashes,abashing,abashment,abashments,abasing,abatable,abate,abated,abatement,abatements,abater,abaters,abates,abating,abatis,abatises,abator,abattoir,abattoirs,abbacies,abbacy ,abbatial,abbe,abbes,abbess,abbesses";

assertEquals(expect, actual);

As it happens these strings are not exactly the same so you get this failure message when you run the test in IntelliJ:

org.junit.ComparisonFailure: 
Expected :a,aah,aahed,aahing,aahs,aardvark,aardvarks,aardwolf,ab,abaci,aback,abacus,abacuses,abaft,abalone,abalones,abandon,abandoned,abandonedly,abandonee,abandoner,abandoners,abandoning,abandonment,abandonments,abandons,abase,abased,abasedly,abasement,abaser,abasers,abases,abash,abashed,abashedly,abashes,abashing,abashment,abashments,abasing,abatable,abate,abated,abatement,abatements,abater,abaters,abates,abating,abatis,abatises,abator,abattoir,abattoirs,abbacies,abbacy,abbatial,abbe,abbes,abbess,abbesses
Actual   :a,aah,aahed,aahing,aahs,aardvark,aardvarks,aardwolf,ab,abaci,aback,abacus,abacuses,abaft,abalone,abalones,abandon,abandoned,abandonedly,abandonee,abandoner,abandoners,abandoning,abandonment,abandonments,abandons,abase,abased,abasedly,abasement,abaser,abasers,abases,abash,abashed,abashedly,abashes,abashing,abashment,abashments,abasing,abatable,abate,abated,abatement,abatements,abater,abaters,abates,abating,abatis,abatises,abator,abattoir,abattoirs,abbacies,abbacy ,abbatial,abbe,abbes,abbess,abbesses

 

The error messages isn't particularly helpful to say the least....

Fortunately IntelliJ provides us with a 'click to see the difference dialog' - but when you click and open the dialog, although it will highlight the difference it's really not immediately obvious where the differences are and you end up scrolling a very long way to find them. And it's certainly impossible to see all the differences at a glance.



So here's the tip instead of this:

assertEquals(expect, actual);

Insert new lines into your string as below:

assertEquals(expect.replace(',', '\n'), actual.replace(',', '\n'));

Then when you click to see the difference you get a dialog that looks like this and you 
are able to see the issues at a glance. Simple but effective.


 





1 comment:

  1. This tip can be generalized. It's often more convenient to dump some complex structure (tree, table, graph) into String and compare this String with reference value, rather than to explore each value of structure by getter and own assertion, one at a time.

    Such a solution has stricter requirements on toString (or special) method which must provide kind-of normalized, reproducible snapshot of state of object (no default @identityhashcodes, no fields outside test scope, stable collection ordering, nice-to-haves like indentation, simple ascii graphics...) but these features are usually easy to implement.

    Except better readability mentioned in blogpost, another reward of such an approach is visualization of structure for debugging and reporting all errors at once.

    Another different question might be whether a test which needs such a long data is not too complex.

    ReplyDelete