简体   繁体   English

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

[英]Comparing two XML strings/files in Groovy/Java

I'm writing unit tests for checking some XML builder. 我正在编写单元测试来检查一些XML构建器。

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. 我尝试使用XmlUtil.serialize()来规范化xml,但这似乎保留了空白,留下了语法上的差异。

How can I get the normalized/canonical form of xml strings in order to make my tests more robust? 我怎样才能获得xml字符串的规范化/规范形式,以使我的测试更加健壮?

I'm writing a Grails application, so I'm fine with any solution in Groovy or Java. 我正在编写一个Grails应用程序,所以我对Groovy或Java中的任何解决方案都很好。

You can use the Groovy XMLUnit utility like this: 您可以像这样使用Groovy XMLUnit实用程序:

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. 比较XML文件而忽略语法差异。

The question and the accepted answer (as of today) correspond to a legacy version of XMLUnit . 问题和接受的答案(截至今天)对应于XMLUnit的遗留版本。

For those interested in knowing how to do it with XMLUnit v2 on Groovy: 对于那些有兴趣知道如何在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()
}

Perhaps there is a "groovier" way of doing it but I think it's OK for illustration purposes :) 也许有一种“更加时髦”的方式,但我觉得它可以用于插图目的:)

Older question, but maybe interesting for future use. 较老的问题,但可能有趣,以备将来使用。
Another possibility, that works not only for XML, but could also be used for your problem. 另一种可能性,不仅适用于XML,还可以用于您的问题。

For Tests like this, you could also use use ApprovalTests ( http://approvaltests.sourceforge.net ), which results in very little code in your unit test. 对于这样的测试,您还可以使用ApprovalTests( http://approvaltests.sourceforge.net ),这会导致单元测试中的代码非常少。

With ApprovalTests you write your test and check your output with the expected output. 使用ApprovalTests,您可以编写测试并使用预期输出检查输出。

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). 简短说明:在测试的第一次运行中,没有预期的输出,因此ApprovalTests写入两个文件 - “已接收”(代码输出)和“已批准”(代码的预期输出)。 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. 这是通过diff工具完成的。 ApprovalTests opens a diff tool and shows the two files in it. ApprovalTests打开diff工具并显示其中的两个文件。 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). 如果输出没有改变(接收==批准),现在所有后续测试运行都将通过。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM