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中的任何解决方案都很满意。
3 个解决方案
#1
16
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文件。
#2
1
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 :)
也许有一种“groovier”的方法,但我认为它可以用于说明目的:)
#3
0
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). 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).
简短描述:在测试的第一次运行中,没有预期的输出,因此ApprovalTests编写两个文件——一个“接收”(代码的输出)和“批准”(代码的预期输出)。在第一次运行中,“已批准”是空的,因为您必须批准代码的输出。这是用diff工具完成的。ApprovalTests打开一个diff工具并显示其中的两个文件。如果代码的输出是您所期望的,那么将输出移动到已批准的文件。现在,如果输出没有更改(received = approved),所有后续测试都将通过。
#1
16
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文件。
#2
1
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 :)
也许有一种“groovier”的方法,但我认为它可以用于说明目的:)
#3
0
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). 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).
简短描述:在测试的第一次运行中,没有预期的输出,因此ApprovalTests编写两个文件——一个“接收”(代码的输出)和“批准”(代码的预期输出)。在第一次运行中,“已批准”是空的,因为您必须批准代码的输出。这是用diff工具完成的。ApprovalTests打开一个diff工具并显示其中的两个文件。如果代码的输出是您所期望的,那么将输出移动到已批准的文件。现在,如果输出没有更改(received = approved),所有后续测试都将通过。