当你有一个简单的方法,例如sum(int x,int y)时,很容易编写单元测试。您可以检查该方法是否正确求和两个样本整数,例如2 + 3应该返回5,然后您将检查相同的一些“非常”数字,例如负值和零。每个都应该是单独的单元测试,因为单个单元测试应该包含单个断言。
当您有复杂的输入输出时,您会怎么做?以一个Xml解析器为例。您可以使用单个方法解析(String xml)来接收String并返回Dom对象。您可以编写单独的测试,检查某些文本节点是否正确解析,属性是否已解析,该子节点属于父节点等。对于所有这些,我可以编写一个简单的输入,例如
<root><child/></root>
将用于检查节点之间的父子关系等,以满足其他期望。
现在,看看下面的Xml:
<root>
<child1 attribute11="attribute 11 value" attribute12="attribute 12 value">Text 1</child1>
<child2 attribute21="attribute 21 value" attribute22="attribute 22 value">Text 2</child2>
</root>
为了检查该方法是否正常工作,我需要检查许多复杂的条件,比如attribute11和attribute12属于element1,Text 1属于child1等。我不想放置多个断言在我的单元测试中。我该如何实现?
答案 0 :(得分:4)
您需要的只是在单独的测试中检查SUT(被测系统)的一个方面。
[TestFixture]
public class XmlParserTest
{
[Test, ExpectedException(typeof(XmlException))]
public void FailIfXmlIsNotWellFormed()
{
Parse("<doc>");
}
[Test]
public void ParseShortTag()
{
var doc = Parse("<doc/>");
Assert.That(doc.DocumentElement.Name, Is.EqualTo("doc"));
}
[Test]
public void ParseFullTag()
{
var doc = Parse("<doc></doc>");
Assert.That(doc.DocumentElement.Name, Is.EqualTo("doc"));
}
[Test]
public void ParseInnerText()
{
var doc = Parse("<doc>Text 1</doc>");
Assert.That(doc.DocumentElement.InnerText, Is.EqualTo("Text 1"));
}
[Test]
public void AttributesAreEmptyifThereAreNoAttributes()
{
var doc = Parse("<doc></doc>");
Assert.That(doc.DocumentElement.Attributes, Has.Count(0));
}
[Test]
public void ParseAttribute()
{
var doc = Parse("<doc attribute11='attribute 11 value'></doc>");
Assert.That(doc.DocumentElement.Attributes[0].Name, Is.EqualTo("attribute11"));
Assert.That(doc.DocumentElement.Attributes[0].Value, Is.EqualTo("attribute 11 value"));
}
[Test]
public void ChildNodesInnerTextAtFirstLevel()
{
var doc = Parse(@"<root>
<child1>Text 1</child1>
<child2>Text 2</child2>
</root>");
Assert.That(doc.DocumentElement.ChildNodes, Has.Count(2));
Assert.That(doc.DocumentElement.ChildNodes[0].InnerText, Is.EqualTo("Text 1"));
Assert.That(doc.DocumentElement.ChildNodes[1].InnerText, Is.EqualTo("Text 2"));
}
// More tests
.....
private XmlDocument Parse(string xml)
{
var doc = new XmlDocument();
doc.LoadXml(xml);
return doc;
}
}
这种方法有很多好处:
UPD:看看Gerard Meszaros(xUnit测试模式的作者书)关于主题的内容:xunitpatterns
一个可能有争议的方面 验证每个测试的一个条件是什么 我们的意思是“一个条件”。一些测试 司机坚持每一个断言 测试。这种坚持可以基于 使用每个Fixture的Testcase类 组织测试方法和 根据一个测试命名每个测试 断言正在验证(例如 AwaitingApprovalFlight.validApproverRequestShouldBeApproved)。 每次测试都有一个断言 这样的命名很容易,但确实很有用 如果我们有更多的测试方法 在许多输出字段上断言。的 当然,我们经常可以遵守这一点 通过提取自定义来解释 断言(第X页)或验证 方法(参见自定义断言)即 允许我们减少倍数 断言方法调用一个。 有时这会使测试更多 可读但如果没有,我 不会太教条 坚持一个断言。
答案 1 :(得分:1)
多项测试。
答案 2 :(得分:1)
使用多个测试。同样的限制适用。您应该测试一些正常的操作案例,一些失败案例和一些边缘案例。
同样地,你可以假设如果sum(x,y)适用于x的某些值,它将与其他值一起使用,你可以假设如果XML解析器可以解析2个节点的序列,它可以还解析了100个节点的序列。
答案 3 :(得分:1)
详细说明Ian的简洁回答:将XML的设置作为设置,并进行单独的单独测试,每个测试都有自己的断言。这样你就不会重复设置逻辑,但你仍然可以很好地了解解析器的错误。
答案 4 :(得分:0)
使用Nunit Fluent语法
Assert.That( someString,
Is.Not.Null
.And.Not.Empty
.And.EqualTo("foo")
.And.Not.EqualTo("bar")
.And.StartsWith("f"));
答案 5 :(得分:0)
我有类似的要求,我希望各种输入集有1个Assert。请关闭下面的链接,我在博客上写道。
这也适用于你的概率。构造一个工厂类,其中包含构造“复杂”输入集的逻辑。单元测试用例只有一个Assert。
希望这有帮助。
谢谢, 维杰。
答案 6 :(得分:0)
您可能还想使用自己的断言(这取自您自己的问题):
attribute11和attribute12属于element1
('attribute11 ', 'attribute12').belongsTo('element1');
或
('element1 attribute11').length
BTW,这与jQuery类似。您将此字符串存储在复杂的图形存储库中。您如何对一个非常复杂的图形连接数据库进行单元测试?