1

I am using XMLUnit for my JUnit tests and I would like to configure it so as to ignore differences related to alternative (but equivalent) rendering of certain types. E.g. 3.14 vs 3.140 for xs:float fields. I guess a full solution would require the tests to be XSD-aware so that the type of each field is known and nuanced comparisons be made in all cases (e.g. true/1 for xs:boolean and perhaps even going so far as to account for default attribute values). At any rate, I am willing to accept workarounds so that I can get my tests running without all those false alarms.

An SSCCE (without the JUnit machinery for easier reproduction) is given below:

import org.custommonkey.xmlunit.XMLTestCase;
import org.custommonkey.xmlunit.XMLUnit;
import org.custommonkey.xmlunit.Diff;


class XMLTestCaseConcrete extends XMLTestCase {
}


public class FooMain {

    public static void main(String args[]) throws Exception {
        String s1 = "<a>180</a>";
        String s2 = "<a>180.0</a>";
        Diff diff = XMLUnit.compareXML(s1, s2);
        System.out.printf("difference below:\n------\n%s\n------\n", diff);
        XMLTestCase xmlTest = new XMLTestCaseConcrete();
        xmlTest.assertXMLEqual(s1, s2);
    }    
}
Marcus Junius Brutus
  • 26,087
  • 41
  • 189
  • 331
  • 1
    Since you're producing and consuming XML already, I presume you have a library which reads/writes the XML from your own Java classes. So I think the easiest way to be flexible about the format is to parse the XML into objects and compare those objects. That's how I handle this sort of flexibility when checking JSON output. As for the XML level, the values 180 and 180.0 are technically different (i.e. 180 implies +/- 0.5 whereas 180.0 implies +/- 0.05), so it sounds like a roll-your-own situation if you absolutely need the flexibility. – Dave Jan 18 '15 at 18:16
  • Of course, it's also important to ask yourself whether you *should* allow this flexibility. If the value could be 180 in one situation and 180.0 in another, without any real difference in meaning, maybe the spec is too ambiguous? – Dave Jan 18 '15 at 18:17

2 Answers2

4

XMLUnit isn't schema aware, so full solution would be quite convoluted. The way to go is to implement a custom DifferenceListener.

The example package contains a FloatingPointTolerantDifferenceListener that does what you need for arbitrary text nodes or attributes, but it will do so for everything that looks like a number - and it doesn't deal with any of the other schema types or default values.

Stefan Bodewig
  • 3,260
  • 15
  • 22
1

In the end I implemented this at the application layer by using (during internalization) a custom Java class to represent xs:float that also "remembers" the exact String representation it came from, so during a subsequent serialization the exact same String form is used (assuming of course it hasn't been altered by the application logic after internalization). Effectively, the only difference between this solution and a simpler and more straightforward one that treats xs:floats as java.lang.Strings at the Java object layer is the additional semantical information provided by using a specialized Float-like type.

At any rate this solution allows me to use both the testing approach suggested by @Dave in the comments to my original question and also the more stringent test of requiring identical XML to be produced after a round of internalization-serialization.

Marcus Junius Brutus
  • 26,087
  • 41
  • 189
  • 331