当前位置 : 主页 > 手机开发 > 其它 >

单元测试 – 如何对具有复杂输入输出的方法进行单元测试

来源:互联网 收集:自由互联 发布时间:2021-06-22
当你有一个简单的方法,例如sum(int x,int y)时,很容易编写单元测试.您可以检查该方法是否正确总和两个样本整数,例如2 3应该返回5,然后您将检查相同的一些“非常”数字,例如负值和零.每
当你有一个简单的方法,例如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>

为了检查该方法是否正常工作,我需要检查许多复杂的条件,例如属性11和属性12属于element1,文本1属于child1等.我不想在我的单元测试中放置多个断言.我怎么能做到这一点?

您所需要的只是在单独的测试中检查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

One possibly contentious aspect of Verify One Condition per Test is what we mean by “one condition”. Some test drivers insist on one assertion per test. This insistence may be based on using a Testcase Class per Fixture organization of the Test Methods and naming each test based on what the one assertion is verifying(E.g. AwaitingApprovalFlight.validApproverRequestShouldBeApproved.). Having one assertion per test makes such naming very easy but it does lead to many more test methods if we have to assert on many output fields. Of course, we can often comply with this interpretation by extracting a Custom Assertion (page X) or Verification Method (see Custom Assertion) that allows us to reduce the multiple assertion method calls into one. Sometimes that makes the test more readable but when it doesn’t, I wouldn’t be too dogmatic about insisting on a single assertion.

网友评论