在Groovy/Java中比较两个XML字符串/文件

10

我将为一些XML构建器编写单元测试。

现在我遇到了一个问题,即使它们的语义相同,但预期结果和实际结果之间存在语法差异。

例如:

预期结果:

<parent><child attr="test attribute">text here</child></parent>

实际结果:
<parent>
  <child attr="test attribute">
    text here
  </child>
</parent>

我尝试使用XmlUtil.serialize()对xml进行规范化,但是这似乎会保留空格,导致语法上的差异。
为了使我的测试更加健壮,我该如何获取xml字符串的规范化/规范形式?
我正在编写一个Grails应用程序,因此我可以接受任何Groovy或Java的解决方案。

如果您得到这个,有什么区别? - Bhavik Ambani
3个回答

19

您可以像这样使用 Groovy XMLUnit 工具:

XMLUnit.setIgnoreWhitespace(true)
XMLUnit.setIgnoreComments(true)
XMLUnit.setIgnoreDiffBetweenTextAndCDATA(true)
XMLUnit.setNormalizeWhitespace(true)

XMLUnit.compareXML(expectedXml, actualXml)

在忽略语法差异的情况下比较 XML 文件。


这是否允许忽略比较中的某些元素,例如时间戳? - Dirk Horsten

5

今天的问题和被接受的答案对应于遗留版本的 XMLUnit

对于那些想了解如何在 Groovy 上使用 XMLUnit v2 的人:

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()
}

也许有更加时髦的方法,但我认为这种方式可以作为示例 :)

0

虽然这是一个老问题,但对于未来的使用可能会有所帮助。

另一种可能性,不仅适用于XML,还可以用于您的问题。

对于这样的测试,您也可以使用ApprovalTests(http://approvaltests.sourceforge.net),这将在单元测试中产生非常少的代码。

使用ApprovalTests编写测试并检查输出与预期输出是否相同。

简短描述: 在第一次运行测试时,没有预期的输出,因此ApprovalTests会写入两个文件-“received”(您的代码输出)和“approved”(您的代码的预期输出)。在第一次运行中,“approved”为空,因为您必须批准您的代码输出。这是通过差异工具完成的。ApprovalTests打开差异工具并在其中显示两个文件。如果您的代码输出符合预期,您就可以将输出移动到已批准的文件中。现在,如果输出不变(received == approved),则所有后续测试运行都将通过。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接