问题
I'm writing unit tests for checking some XML builder.
Now I'm running into the problem of syntactical differences between the expected result and the actual result, despite their identical semantics.
Example:
Expected result:
<parent><child attr="test attribute">text here</child></parent>
Actual result:
<parent>
<child attr="test attribute">
text here
</child>
</parent>
I tried normalizing the xml using XmlUtil.serialize(), however this seems to keep the whitespaces, leaving syntactical differences.
How can I get the normalized/canonical form of xml strings in order to make my tests more robust?
I'm writing a Grails application, so I'm fine with any solution in Groovy or Java.
回答1:
You can use the Groovy XMLUnit utility like this:
XMLUnit.setIgnoreWhitespace(true)
XMLUnit.setIgnoreComments(true)
XMLUnit.setIgnoreDiffBetweenTextAndCDATA(true)
XMLUnit.setNormalizeWhitespace(true)
XMLUnit.compareXML(expectedXml, actualXml)
To compare XML files while ignoring the syntactical differences.
回答2:
The question and the accepted answer (as of today) correspond to a legacy version of XMLUnit.
For those interested in knowing how to do it with XMLUnit v2 on Groovy:
def "XMLs must be identical"() {
setup:
def control = '<foo><bar></bar></foo>'
def test = '''
<foo>
<bar></bar>
</foo>
'''
when:
Diff d = DiffBuilder.compare(Input.fromString(control))
.withTest(Input.fromString(test))
.ignoreWhitespace()
.ignoreComments()
.normalizeWhitespace()
.build()
then:
!d.hasDifferences()
}
Perhaps there is a "groovier" way of doing it but I think it's OK for illustration purposes :)
回答3:
Older question, but maybe interesting for future use.
Another possibility, that works not only for XML, but could also be used for your problem.
For Tests like this, you could also use use ApprovalTests (http://approvaltests.sourceforge.net), which results in very little code in your unit test.
With ApprovalTests you write your test and check your output with the expected output.
Short description: In the first run of your test, there is no expected output, so ApprovalTests writes two files - a "received" (output of your code) and "approved" (expected output of your code). In the first run, the "approved" is empty, because you have to approve the output of your code. This is done with a diff tool. ApprovalTests opens a diff tool and shows the two files in it. If the output of your code is what you expected, you move the output to the approved file. Now all subsequent tests runs will pass, if the output does not change (received == approved).
来源:https://stackoverflow.com/questions/13727876/comparing-two-xml-strings-files-in-groovy-java