zoukankan      html  css  js  c++  java
  • NUnit单元测试笔记Ⅱ基础篇

    使用NUnit编写测试

    构建单元测试                                                

    如果你有一个名为CreateAccount 的被测试函数,俺么你的第一个测试函数的名称也许就是CreateSimpleAccount等等。它会以恰当的参数调用CreateAccount并验证CreateAccount的行为是否和它宣称的一样。当然你也可以有许多测试方法来执行CreateAccount(毕竟,不是所有account都是简单) 。

     

    <截图来自<单元测试之道>>

      

    测试代码仅限于我们内部使用。客户或者最终用户永远都不会看到,更不会使用这些代码。因此,你懂的。

    测试代码必须要做一下这几件事情:

      ● 准备测试所需要的各种条件(创建所有必须的对象,分配必要资源等等)

      ● 调用要测试的方法

      ● 验证被测试方法的行为和期望是否一致。

      ● 完成后清理各种资源。

    NUnit各种断言                                                  

      断言是单元测试最基本的组成部分。因此,NUnit程序库以Assert类的静态方法的形式提供了不同形式的多种断言。

     

      ■ AreEqual

      Assert.AreEqual(expexted, actual[,string message])

      这是使用的最多的断言形式,在上面的参数中,expected是你的期望值(通常是硬编码的),actual是被测试代码实际产生的值,message是一个可选的消息,如果提供的话,就爱你工会在发生错误的时候报告这个消息。

      计算机并不能精确的表示所有的浮点数,通常会有一下偏差。因此,如果你想用断言来比较浮点数(float或者是double)则需要指定一个额外的误差参数。它表明你需要多接近才能认为两数“相等”。

     

      ■ IsNull

      Assert.IsNull(object [ , string message])

      Assert.IsNotNull(object [ , string message])

      验证一个给定的对象是否为null,如果答案为否,则将会失败。Message参数是可选的。

     

      ■ AreSame

      Assert.AreSame(expected, actual [ , string message])

      验证expected参数和actual参数所引用的是否为同一个对象,如果不是的话,将会失败。Message参数是可选的。

     

      ■ IsTrue

      Assert.IsTrue(bool condition , actual [ , string message])

      验证给定的二元条件是否为真,如果假的话,将会失败。Message参数是可选的

     

      ■ Fail

      Assert.Fail([string messge])

      上面的断言将会使测试立即失败,其中message参数是可选的。这种断言通常被用于标记某个不应该被到达的分支,但它在实际中并不常用。

    NUnit框架                                                     

      下面是一段简单的测试代码,它展示了开始使用该框架的最小要求:

        
        using NUnit.Framework;
        [TestFixture]
        public class TestLargest
        {
            [Test]
            public void LargestOf3()
            {
                Assert.AreEqual(-7, Cmp.Largest(new int[] { -9, -8, -7 }));
            }
        }
    
    

     

      首先,第一行的using声明引入了必须的NUnit类。NUnit框架提供了我们需要的单元测试的功能,包括所有我们在前面描述的断言方法。

      接下来,我们看到【TestFixture】特性标记。而且这个类必须声明为public,而且它必须有一个public的、没有参数的构造函数(默认构造函数就行了)。

      最后,测试类包含了用【Test】特性标记的方法。所有用【Test】标记的public方法都会被NUnit自动运行。

    NUnit测试的组成                                                  

      如我们刚才看到的一个【TestFixture】标记的类包含一个或多个测试方法:每个方法包含一个或多个断言。一个程序集可以包含多个testFixture。

      我们可以把现存的多个testFixture 组合进一个testSuite中,一个testSuite是一些testFixture类的集合。用【Suite】特性标记。

      Suite是层次化组织测试的一个很有用的机制。特别是对于无人照料的构建,用它来调整测试集合是非常方便的。

      ■ Categories

      NUnit提供了另一种机制Categories,你可以用它来对每个单独的测试方法和testFixtur分门别类。一个category是指你定义的一个名字。你可以把不同的测试方法关联到一个或多个category,然后在运行测试的时候,选择你想要运行的category。

      比如,你可以使用category来把运行时间较短的测试和运行时间较长的测试分开。显然,前一种测试将经常被运行,后一种则可能只是在夜晚构建的时候才运行一次。

      Category是以attribute特性的形式来指定的。当声明方法的时候,你可以提供一个祖父来指定它的category。然后,在你运行测试的时候,可以指定你要运行那些category(你可以一次执行运行多个category)。

    namespace UnitTest
    {
        [TestFixture]
        public class TestLargest
        {
            [Test]
            [Category("Short")]
            public void LargestOf3()
            {
                Assert.AreEqual(-7, Cmp.Largest(new int[] { /*......*/}));
            }
            [Test,Category("Short")]
            public void LargestOf30()
            { 
                Assert.AreEqual(77,Cmp.Largest(new int[]{ /*......*/ }));
            }
            [Test]
            [Category("Long")]
            public void LargestOf3000()
            {
                Assert.AreEqual(77, Cmp.Largest(new int[] { /*......*/ }));
            }
        }
    }
    
    
    

      你可以分开2行指定多个特性(test和category),也可以写在1行。

      打开NUnit,我们可以看到category选项卡中有short和long,你只需选中要执行的,添加到下面的list里,再excute一下就ok了。

      

     

      ■ Per-method的Setup和Teardown

    每个测试的运行都应该是相互独立的;从而你就可以在任何时候,以任意的顺序运行每个单独的测试。

    为了获得这样的好处,在每个测试开始之前,你都需要重新设置某些测试环境,或者在测试完成之后,你需要释放一些资源。借助于一些Attribute,NUnit让你指定2种方法,分别用于环境的建立和清理:

     [SetUp]
     public void MySetup()
     {/* ..... */ }
     [TearDown]
     public void MyTeardown()
     {/* ..... */ }
    
    

      在这个例子中,在调用每个【Test】方法之前,调用方法MySetup;并且在每个测试方法完成之后,调用方法MyTeardown()。

      比如,如果对于每个测试你都需要某种数据库连接。这时,你就不需要在每个测试方法中重复建立连接和释放连接了,而只须在SetUp和TearDown方法中分别建立和释放连接:

        [TestFixture]
        public class TestDB
    
        {
    
            private Connection dbConn;
    
            [SetUp]
            public void MySetup()
            {
                dbConn = new Connection("oracle", 1521, "user", "psw");
                dbConn.Connect();
            }
    
            [TearDown]
            public void MyTeardown()
            {
                dbConn.Disconnect();
                dbConn = null;
            }
    
            [Test]
            public void TestAccountAccess()
            { }
    
            [Test]
            public void TestEmployeeAccess()
            { }
        }
    
    
    

      ■ Per-class的Setup和Per-class的Teardown

      知道了Per-method,那就容易理解Per-class了。

        

        [TestFixtureSetUp]
        public class OneTimeSutup
        {}
        [TestFixtureTearDown]
        public class OneTimeTeardown
        { }
    

      结合刚才的两个就是

     

     

  • 相关阅读:
    VB操作Excel
    VB二进制文件读写
    VB操作CAD
    什么是管态?什么事用户态?二者有何区别?
    什么是处理机的态?为什么要区分处理机的态?
    综合布线的一些计算题
    在设计操作系统时,可以考虑的结构组织有哪几种?
    什么是操作系统虚拟机?
    Windows、Unix、Linux是什么类型的操作系统?
    操作系统的资源管理功能有哪几个?其中,哪些功能与计算机系统的硬部件相关?
  • 原文地址:https://www.cnblogs.com/TivonStone/p/1839583.html
Copyright © 2011-2022 走看看