在軟件開發(fā)周期中,需要不時地驗證 XML 文檔的結(jié)構(gòu)或內(nèi)容。不管構(gòu)建的是何種應(yīng)用程序,測試 XML 文檔都具有一定的挑戰(zhàn)性,尤其是在沒有相關(guān)工具的情況下更是如此。
本月,我將首先向您說明為何不能 使用 String 比較來驗證 XML 文檔的結(jié)構(gòu)和內(nèi)容。之后,我會介紹 XMLUnit,一個由 Java 開發(fā)人員創(chuàng)建并可服務(wù)于 Java 開發(fā)人員的 XML 驗證工具,向您展示如何使用它來驗證 XML 文檔。
古典的 String 比較
首先,假設(shè)您已經(jīng)構(gòu)建了一個應(yīng)用程序,該應(yīng)用程序可以輸出代表對象依賴性報告的 XML 文檔。對于給定的類和對應(yīng)的過濾器的集合,會生成一個報告來輸出類和類的依賴項(想象一下導(dǎo)入)。
清單 1 顯示了用于給定類列表(com.acme.web.Widget 和 com.acme.web.Account)的報告,過濾器被設(shè)為忽略外部類,比如 java.lang.String:
清單 1. 一個示例依賴性 XML 報告
<DependencyReport date="Sun Dec 03 22:30:21 EST 2006">
<FiltersApplied>
<Filter pattern="java|org"/>
<Filter pattern="net."/>
</FiltersApplied>
<Class name="com.acme.web.Widget">
<Dependency name="com.acme.resource.Configuration"/>
<Dependency name="com.acme.xml.Document"/>
</Class>
<Class name="com.acme.web.Account">
<Dependency name="com.acme.resource.Configuration"/>
<Dependency name="com.acme.xml.Document"/>
</Class>
</DependencyReport>
清單 1 很明顯是由應(yīng)用程序生成的;因而,第一層測試是驗證應(yīng)用程序是否真能生成一個文檔。一旦驗證了這一點,可以繼續(xù)測試指定文檔的其他三個方面:
結(jié)構(gòu)
內(nèi)容
指定內(nèi)容
可以通過單獨使用 JUnit 利用 String 比較處理上述前兩個方面,如清單 2 所示:
清單2. 硬性驗證 XML
public class XMLReportTest extends TestCase {
private Filter[] getFilters(){
Filter[] fltrs = new Filter[2];
fltrs[0] = new RegexPackageFilter("java|org");
fltrs[1] = new SimplePackageFilter("net.");
return fltrs;
}
private Dependency[] getDependencies(){
Dependency[] deps = new Dependency[2];
deps[0] = new Dependency("com.acme.resource.Configuration");
deps[1] = new Dependency("com.acme.xml.Document");
return deps;
}
public void testToXML() {
Date now = new Date();
BatchDependencyXMLReport report =
new BatchDependencyXMLReport(now, this.getFilters());
report.addTargetAndDependencies(
"com.acme.web.Widget", this.getDependencies());
report.addTargetAndDependencies(
"com.acme.web.Account", this.getDependencies());
String valid = "<DependencyReport date="" + now.toString() + "">"+
"<FiltersApplied><Filter pattern="java|org" /><Filter pattern="net." />"+
"</FiltersApplied><Class name="com.acme.web.Widget">" +
" <Dependency name="com.acme.resource.Configuration" />"+
"<Dependency name="com.acme.xml.Document" /></Class>"+
"<Class name="com.acme.web.Account">"+
"<Dependency name="com.acme.resource.Configuration" />"+
"<Dependency name="com.acme.xml.Document" />"+
"</Class></DependencyReport>";
assertEquals("report didn't match xml", valid, report.toXML());
}
}