在软件开发周期中,需要不时地验证 XML 文档的结构或内容。不管构建的是何种应用程序,测试 XML 文档都具有一定的挑战性,尤其是在没有相关工具的情况下更是如此。
本月,我将首先向您说明为何不能 使用 String 比较来验证 XML 文档的结构和内容。之后,我会介绍 XMLUnit,一个由 Java 开发人员创建并可服务于 Java 开发人员的 XML 验证工具,向您展示如何使用它来验证 XML 文档。
古典的 String 比较
首先,假设您已经构建了一个应用程序,该应用程序可以输出代表对象依赖性报告的 XML 文档。对于给定的类和对应的过滤器的集合,会生成一个报告来输出类和类的依赖项(想象一下导入)。
清单 1 显示了用于给定类列表(com.acme.web.Widget 和 com.acme.web.Account)的报告,过滤器被设为忽略外部类,比如 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 很明显是由应用程序生成的;因而,第一层测试是验证应用程序是否真能生成一个文档。一旦验证了这一点,可以继续测试指定文档的其他三个方面:
结构
内容
指定内容
可以通过单独使用 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());
}
}