相似但不相同!
當(dāng)使用 IgnoreTextAndAttributeValuesDifferenceListener 類時,必須聲明這兩個文檔是 similar 而非 identical。如果錯誤地調(diào)用了 identical,那么需要處理屬性值。
當(dāng)然,DTD 的模式和 XML 模式都有助于 XML 結(jié)構(gòu)驗證,然而,有時文檔并不需要引用它們 —— 在這些場景下,結(jié)構(gòu)驗證可能會很有用。同樣,如果需要忽略特定的一些值(例如那些 Date 值),可以實(shí)現(xiàn) DifferenceListener 接口(正如 IgnoreTextAndAttributeValuesDifferenceListener 所做的一樣)并提供一個定制實(shí)現(xiàn)。
XMLUnit 和 XPath
為實(shí)現(xiàn) XML 測試的所有三個方面,XMLUnit 還可以借助 XPath 進(jìn)行 XML 文檔特定部分的驗證。
例如,使用清單 1 所示相同的格式,我想驗證由應(yīng)用程序生成的第一個 Class 元素的 name 屬性值是否是 com.acme.web.Widget。要實(shí)現(xiàn)此目的,我必須創(chuàng)建一個 XPath 表達(dá)式來導(dǎo)航到準(zhǔn)確的位置;而且,XMLUnit 的 XMLTestCase 提供了一個方便的 assertXpathExists() 方法,這意味著我必須現(xiàn)在擴(kuò)展 XMLTestCase。
清單 8. 使用 XPath 來驗證準(zhǔn)確的 XML 值
public void testToXMLFormatOnly() throws Exception{
BatchDependencyXMLReport report =
new BatchDependencyXMLReport(new Date(), this.getFilters());
report.addTargetAndDependencies(
"com.acme.web.Widget", this.getDependencies());
report.addTargetAndDependencies(
"com.acme.web.Account", this.getDependencies());
assertXpathExists("//Class[1][@name='com.acme.web.Widget']",
report.toXML());
}
如清單 8 所示,XMLUnit 和 XPath 一起協(xié)作提供了可以準(zhǔn)確驗證 XML 文檔 的一種便捷機(jī)制,而不是進(jìn)行大規(guī)模的差異測試。請記住要在 XMLUnit 內(nèi)充分利用 XPath,您的測試用例必須要擴(kuò)展 XMLTestCase。如果熟悉 XPath 也會大有幫助!
XPath 是什么?
XPath 或 XML Path Language 是一種表達(dá)式語言,用來基于樹表示定位 XML 文檔的各部分。XPath 允許您導(dǎo)航 XML 文檔并可以幫您選擇文檔值。
為何要舍近求遠(yuǎn)呢?
XMLUnit 是一種基于 Java 的開放源碼工具,它使測試 XML 文檔更為簡單和靈活,而這是使用 String 比較所達(dá)不到的。使用 XMLUnit 進(jìn)行差異測試所存在的惟一缺點(diǎn)是測試會依賴于文件系統(tǒng)來加載控制文檔。在編寫測試時,請務(wù)必考慮這一附加的依賴性。
雖然 XMLUnit 已經(jīng)有段時間沒有發(fā)布任何更新了,但它當(dāng)前的特性集已經(jīng)足夠健壯來應(yīng)對各種測試沖擊,并且它用在這種情況下基本上是免費(fèi)的!