xsd部分の属性が単体テストの値と一致しないのに、プログラムがXML単体テストに合格する理由を見つけるという任務を負っています。問題は、XMLやxsdについてほとんど何も知らないことです。私はさまざまな場所でそれを読みましたが、何もテストが失敗する理由を理解するのに役立ちました。
なぜそれが機能しないのかを理解する前に、ユニットテストを行うメソッドで何が起こっているのかを理解する必要があるようです。ほとんど把握していると思いますが、よくわからない部分もあります。この部分はxsdも扱います。
これが私のxsdです:
public static class Constants
{
public const string Xsd = @"
<xs:schema elementFormDefault=""qualified"" xmlns:xs=""http://www.w3.org/2001/XMLSchema"">
<xs:element name=""Datas"">
<xs:complexType>
<xs:sequence>
<xs:element name=""Data"">
<xs:attributeGroup ref=""allocData""/>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:attributeGroup id=""allocData"">
<xs:attribute name=""Site"" type=""string""/>
<xs:attribute name=""MonthNum"" type=""string""/>
<xs:attribute name=""Department"" type=""string""/>
<xs:attribute name=""Numerator"" type=""float""/>
<xs:attribute name=""Data_Indicator"" type=""string""/>
<xs:attribute name=""Industry_Benchmark"" type=""int""/>
<xs:attribute name=""OSHA_Benchmark"" type=""int""/>
<!--xs:attribute name=""Comments"" type=""string""/-->
<xs:attribute name=""Executive_Comments"" type=""string""/>
<xs:attribute name=""Fleet_Executive_Comments"" type=""string""/>
</xs:attributeGroup>
</xs:schema>";
これが私の単体テストの方法です。
public void XMLTest()
{
List<DataResults> ListOfResults = new List<DataResults>();
DataResults r1 = new DataResults();
DataResults r2 = new DataResults();
HarvesterHandle testData = new HarvesterHandle();
r1.Site = "Springfield Site";
r1.Department = "Freak";
r1.MonthNum = "8";
r1.Numerator = 65807;
r1.Data_Indicator = "A12";
// r1.Comments = "Hello, World";
r1.Industry_Benchmark = 23;
r1.OSHA_Benchmark = 2;
r1.ExecutiveComments = "It costs HOW MUCH?";
r1.FleetExecComments = "No you can't have a new car";
r2.Site = "Joplin Site";
r2.Department = "Rock";
r2.MonthNum = "12";
r2.Numerator = 65625;
r2.Data_Indicator = "Ou812";
r2.Industry_Benchmark = 523;
r2.OSHA_Benchmark = 2456;
// r2.Comments = "GoodBye, World!";
r2.ExecutiveComments = "Cut it!";
r2.FleetExecComments = "It only has 250,000 miles";
ListOfResults.Add(r1);
ListOfResults.Add(r2);
var test = testData.XMLTest(ListOfResults);
var xmlDoc = XDocument.Parse(test.ToString());
XmlSchemaSet set = new XmlSchemaSet();
set.Add(XmlSchema.Read(XElement.Parse(Constants.Xsd).CreateReader(), (o, e) => { })); bool valid = true;
xmlDoc.Validate(set, (o, e) =>
{
valid = false;
});
Assert.IsTrue(valid);
var element = test.Descendants("Data").FirstOrDefault(x => x.Attribute("Site").Value.Equals(r1.Site));
Assert.IsNotNull(element);
Assert.AreEqual(r1.Site, element.Attribute("Site").Value);
Assert.AreEqual(r1.Department, element.Attribute("Department").Value);
Assert.AreEqual(r1.MonthNum.ToString(), element.Attribute("MonthNum").Value);
Assert.AreEqual(r1.Numerator.ToString(), element.Attribute("Numerator").Value);
Assert.AreEqual(r1.Data_Indicator, element.Attribute("Data_Indicator").Value);
Assert.AreEqual(r1.Industry_Benchmark.ToString(), element.Attribute("Industry_Benchmark").Value);
Assert.AreEqual(r1.OSHA_Benchmark.ToString(), element.Attribute("OSHA_Benchmark").Value);
// Assert.AreEqual(r1.Comments.ToString(), element.Attribute(
// "Comments").Value);
Assert.AreEqual(r1.ExecutiveComments.ToString(), element.Attribute("Executive_Comments").Value);
Assert.AreEqual(r1.FleetExecComments.ToString(), element.Attribute("Fleet_Executive_Comments").Value);
element = test.Descendants("Data").FirstOrDefault(x => x.Attribute("Site").Value.Equals(r2.Site));
Assert.IsNotNull(element);
Assert.AreEqual(r2.Site, element.Attribute("Site").Value);
Assert.AreEqual(r2.Department, element.Attribute("Department").Value);
Assert.AreEqual(r2.MonthNum.ToString(), element.Attribute("MonthNum").Value);
Assert.AreEqual(r2.Numerator.ToString(), element.Attribute("Numerator").Value);
Assert.AreEqual(r2.Data_Indicator, element.Attribute("Data_Indicator").Value);
Assert.AreEqual(r2.Industry_Benchmark.ToString(), element.Attribute("Industry_Benchmark").Value);
Assert.AreEqual(r2.OSHA_Benchmark.ToString(), element.Attribute("OSHA_Benchmark").Value);
// Assert.AreEqual(r2.Comments.ToString(), element.Attribute(
// "Comments").Value);
Assert.AreEqual(r2.ExecutiveComments.ToString(), element.Attribute(Executive_Comments").Value);
Assert.AreEqual(r2.FleetExecComments.ToString(), element.Attribute("Fleet_Executive_Comments").Value);
}
xsdを扱っているように見える部分はこれです:
XmlSchemaSet set = new XmlSchemaSet();
set.Add(XmlSchema.Read(XElement.Parse(Constants.Xsd).CreateReader(), (o, e) => { })); bool valid = true;
xmlDoc.Validate(set, (o, e) =>
{
valid = false;
});
Assert.IsTrue(valid);
問題は、xsdの属性データ型が実際のデータと一致しない場合でも、テストに合格することです。たとえば、文字列属性(MonthNum、Siteなど)のいずれかがfloatに変更された場合でも、テストは合格です。また、.xsd要素名DatasおよびDataがFredやEthylのようなものに変更された場合でも、テストは合格です。
xmlユニットテストメソッドのコードのxsd部分が何をしていても、正しいデータ型や要素名をチェックしていないと思います。
リクエストごとに、ここに私のxmlがあります:
public const string XSLT = @"
<xsl:stylesheet version=""1.0"" xmlns:xsl=""http://www.w3.org/1999/XSL/Transform"">
<xsl:output method=""text"" encoding=""us-ascii"" />
<xsl:template match=""/"">Site, MonthNum, Department, Numerator, Denominator, Data_Indicator, Industry_Benchmark, OSHA_Benchmark, <!--Comments--> Executive_Comments, Fleet_Executive_Comments,
<xsl:for-each select=""Datas/Data"">
<xsl:text>'</xsl:text>
<xsl:value-of select=""@site""/>
<xsl:text>','</xsl:text>
<xsl:value-of select=""@monthNum""/>
<xsl:text>','</xsl:text>
<xsl:value-of select=""@Department""/>
<xsl:text>','</xsl:text>
<xsl:value-of select=""@numerator""/>
<xsl:text>','</xsl:text>,
<xsl:value-of select=""Industry_Benchmark""/>
<xsl:text>'</xsl:text>,
<xsl:value-of select=""OSHA_Benchmark""/>
<xsl:text>'</xsl:text>,
<!--xsl:value-of select=""Comments""/-->
<!--xsl:text>'</xsl:text-->,
<xsl:value-of select=""Executive_Comments""/>
<xsl:text>'</xsl:text>,
<xsl:value-of select=""Fleet_Executive_Comments""/>
<xsl:text>'</xsl:text>,
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>";
}
}
編集:これは、テストの実行時に生成されるXMLです。
<Data>
<Data Site="Springfield Site" MonthNum="8" Department="Freak" Numerator="65807" Data_Indicator="A12" Industry_Benchmark="23" OSHA_Benchmark="2" Executive_Comments="It costs HOW MUCH?" Fleet_Executive_Comments="No you can't have a new car" />
<Data Site="Joplin Site" MonthNum="12" Department="Rock" Numerator="65625" Data_Indicator="Ou812" Industry_Benchmark="523" OSHA_Benchmark="2456" Executive_Comments="Cut it!" Fleet_Executive_Comments="It only has 250,000 miles" />
</Data>