C# 单元测试XML生成
人们推荐什么样的单元测试策略来正确生成xml 我目前的测试似乎有点原始,大致如下:C# 单元测试XML生成,c#,xml,unit-testing,nunit,C#,Xml,Unit Testing,Nunit,人们推荐什么样的单元测试策略来正确生成xml 我目前的测试似乎有点原始,大致如下: [Test] public void pseudo_test() { XmlDocument myDOC = new XmlDocument(); mydoc = _task.MyMethodToMakeXMLDoc(); Assert.AreEqual(myDoc.OuterXML(),"big string of XML") } 为什么不假设某个商业xml解析器是正确的,并根据它验证xm
[Test]
public void pseudo_test()
{
XmlDocument myDOC = new XmlDocument();
mydoc = _task.MyMethodToMakeXMLDoc();
Assert.AreEqual(myDoc.OuterXML(),"big string of XML")
}
为什么不假设某个商业xml解析器是正确的,并根据它验证xml代码?差不多
Assert.IsTrue(myDoc.Xml.ParseOK)
除此之外,如果您想彻底了解,我认为您必须自己构建一个解析器,并验证xml规范要求的每个规则。另一种可能是使用XmlReader并检查错误计数>0。大概是这样的:
void CheckXml()
{
string _xmlFile = "this.xml";
string _xsdFile = "schema.xsd";
StringCollection _xmlErrors = new StringCollection();
XmlReader reader = null;
XmlReaderSettings settings = new XmlReaderSettings();
settings.ValidationEventHandler += new ValidationEventHandler(this.ValidationEventHandler);
settings.ValidationType = ValidationType.Schema;
settings.IgnoreComments = chkIgnoreComments.Checked;
settings.IgnoreProcessingInstructions = chkIgnoreProcessingInstructions.Checked;
settings.IgnoreWhitespace = chkIgnoreWhiteSpace.Checked;
settings.Schemas.Add(null, XmlReader.Create(_xsdFile));
reader = XmlReader.Create(_xmlFile, settings);
while (reader.Read())
{
}
reader.Close();
Assert.AreEqual(_xmlErrors.Count,0);
}
void ValidationEventHandler(object sender, ValidationEventArgs args)
{
_xmlErrors.Add("<" + args.Severity + "> " + args.Message);
}
void CheckXml()
{
字符串_xmlFile=“this.xml”;
字符串_xsdFile=“schema.xsd”;
StringCollection_xmlErrors=新建StringCollection();
XmlReader=null;
XmlReaderSettings设置=新建XmlReaderSettings();
settings.ValidationEventHandler+=新的ValidationEventHandler(this.ValidationEventHandler);
settings.ValidationType=ValidationType.Schema;
settings.IgnoreComments=chkignorecommons.Checked;
settings.IgnoreProcessingInstructions=chkIgnoreProcessingInstructions.Checked;
settings.IgnoreWhitespace=chkIgnoreWhiteSpace.Checked;
settings.Schemas.Add(null,XmlReader.Create(_xsdFile));
reader=XmlReader.Create(xmlFile,settings);
while(reader.Read())
{
}
reader.Close();
Assert.AreEqual(xmlErrors.Count,0);
}
void ValidationEventHandler(对象发送方,validationEventTargs参数)
{
_添加(“+args.Message”);
}
如果您有一个期望输出的标准格式,为什么不创建一个XML模式或DTD并根据它进行验证呢。这将不依赖于数据,因此将是灵活的。在设计系统时,定义XML的形成方式也会很有帮助。根据XML模式或DTD进行验证,还要检查节点是否具有所需的值 可能会帮助您。使用XmlSchema类根据XSD模式验证它。我想它可以在System.XML下找到。
另一种选择是编写序列化类(XMLSerializer),将XML反序列化为对象。这样做的好处是,它将隐式地验证您的结构,然后可以使用结果对象轻松访问这些值进行测试 首先,正如几乎所有人都说的,如果有为XML定义的模式,请验证XML。(如果没有,请定义一个。) 但是,通过对文档执行XPath查询,您可以构建比这更细粒度的测试,例如:
string xml="Your xml string here" ;
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
path = "/doc/element1[@id='key1']/element2[. = 'value2']";
Assert.IsTrue(doc.SelectSingleNode(path) != null);
这样,您不仅可以测试文档是否在语义上有效,还可以测试生成文档的方法是否使用您期望的值填充文档。使用模式进行验证的另一个原因是,虽然XML节点是显式排序的,但XML属性不是 因此,您的字符串比较:
Assert.AreEqual(myDoc.OuterXML(),"big string of XML")
如果属性的顺序不同,则会失败,如果一位XML是手动创建的,另一位是通过编程创建的,则很容易发生这种情况。验证生成的文档格式是否正确 验证生成的文档是否有效 验证生成的文档是否正确 假设您正在用有用的数据制作一个XML文档,因此您需要确保您的测试具有正确的输入覆盖率。我看到的最常见的问题是
- 错误转义的元素
- 错误转义的属性
- 错误转义的元素名称
- 错误转义的属性名称
xElementA.Should().Be(xElementB);
xDocument.Should().HaveRoot("configuration");
xDocument.Should().HaveElement("settings");
xElement.Should().HaveAttribute("age", "36");
xElement.Should().HaveElement("address");
xAttribute.Should().HaveValue("Amsterdam");
请注意,这适用于LINQtoXML,而不是原始问题中指定的XmlDocument对象,但就我个人而言,这些天我发现我使用LINQtoXML作为第一选择
如果您想添加更多的XML断言以满足您的需要,它也很容易扩展。您可以使用DTD
XMLUnit.setIgnoreWhitespace(true);
XMLUnit.setIgnoreDiffBetweenTextAndCDATA(true);
Diff diff = new Diff(expectedDocument, obtainedDocument);
XMLAssert.assertXMLIdentical("xml invalid", diff, true);
public class IgnoreVariableAttributesDifferenceListener implements DifferenceListener {
private final List<String> IGNORE_ATTRS;
private final boolean ignoreAttributeOrder;
public IgnoreVariableAttributesDifferenceListener(List<String> attributesToIgnore, boolean ignoreAttributeOrder) {
this.IGNORE_ATTRS = attributesToIgnore;
this.ignoreAttributeOrder = ignoreAttributeOrder;
}
@Override
public int differenceFound(Difference difference) {
// for attribute value differences, check for ignored attributes
if (difference.getId() == DifferenceConstants.ATTR_VALUE_ID) {
if (IGNORE_ATTRS.contains(difference.getControlNodeDetail().getNode().getNodeName())) {
return RETURN_IGNORE_DIFFERENCE_NODES_IDENTICAL;
}
}
// attribute order mismatch (optionally ignored)
else if (difference.getId() == DifferenceConstants.ATTR_SEQUENCE_ID && ignoreAttributeOrder) {
return RETURN_IGNORE_DIFFERENCE_NODES_IDENTICAL;
}
// attribute missing / not expected
else if (difference.getId() == DifferenceConstants.ATTR_NAME_NOT_FOUND_ID) {
if (IGNORE_ATTRS.contains(difference.getTestNodeDetail().getValue())) {
return RETURN_IGNORE_DIFFERENCE_NODES_IDENTICAL;
}
}
return RETURN_ACCEPT_DIFFERENCE;
}
@Override
public void skippedComparison(Node control, Node test) {
// nothing to do
}
}
XMLUnit.setIgnoreWhitespace(true);
XMLUnit.setIgnoreDiffBetweenTextAndCDATA(true);
Diff diff = new Diff(expectedDocument, obtainedDocument);
diff.overrideDifferenceListener(new IgnoreVariableAttributesDifferenceListener(Arrays.asList("id", "uid"), true));
XMLAssert.assertXMLIdentical("xml invalid", diff, true);