单元测试:Nunit(二)

      作为单元测试的第二部分,和第一部分的间隔时间差的的确有点长了(嘿嘿,自己一直在偷懒)。在第一讲中主要讲的是如何在VS2005中进行单元测试,以及当时选NUnit2.48(.net 2.0)作为学习的版本,和进行了一个小个程序的测试,大致上都知道如何使用NUnitC#编写的代码如何进行单元测试,而在这一讲中则是主要讲讲几个常用的属性(Attribute)

先写一个小小的程序,功能只是在一个数组中找出一个最大的数字。

代码
         public   int  GetLargest( int [] array)
        {
            
if  ( null   ==  array  ||   0   ==  array.Length)
            {
                
throw   new  Exception( " 数组为空! " );
            }

            
int  num  =  Int32.MinValue;

            
for  ( int  i  =   0 ; i  <  array.Length; i ++ )
            {
                
if  (num  <  array[i])
                {
                    num 
=  array[i];
                }
            }

            
return  num;
         }

    同样要建立一个测试类,现在开始逐个介绍一些比较常用的属性。

    一、[TestFixtureSetUp]这个属性标识的函数表示是这个类的初始化函数,测试类一旦执行,首先执行的就是这个属性标识的函数,既然是初始化,那当然一般是初始化一些对象和字段之类的,功能有点类似于构造函数。

        [TestFixtureSetUp]
        
public   void  Init()
        {
            largest 
=   new  Largest();
            Console.WriteLine(
" 我只会在类的最初调用时初始化对象! " );
        }

    二、上面说了初始化,自然的我们要说到销毁了,[TestFixtureTearDown]与初始化对应,此属性标识的函数在类的最后用来销毁对象,根据功能很自然的就想到析构函数。 

代码
        [TestFixtureTearDown]
        
public   void  Terminate()
        {
            
if  ( null   !=  largest)
            {
                largest 
=   null ;
            }
            Console.WriteLine(
" 我只会在类的最后销毁对象! " );
        }

     三、上面说的初始化和销毁都是针对整个测试类来说的,有没有一个可以针对没个测试的case的呢?可以在执行每个case之前进行初始化,在每个case执行之后又可以销毁,这样不就可以让一些公用的对象可以在执行每个case的时候都重新被赋值,不会相互影响。既然都这样说了,当然有了。[SetUp]属性标识的函数可以在每个Test Case的执行之前初始化一次。

        [SetUp]
        
public   void  InitCase()
        {
            largest 
=   new  Largest();
            Console.WriteLine(
" 我会在执行每个Test Case之前初始化对象! " );
        }

       四、直接来看销毁[TearDown].

代码
        [TearDown]
        
public   void  TerminateCase()
        {
            
if ( null   !=  largest)
            {
                largest 
=   null ;
            }
            Console.WriteLine(
" 我会在执行完每个Test Case之后销毁对象! " );
        }

    五、在程序中我们对应空数组抛出了一个异常,那么我们在测试的时候,如果输入的数组是空的会怎么样?看下面一段程序:

        [Test]
        
public   void  TestGetLargest1()
        {
            
int [] numArr  =   new   int [] { };

            largest.GetLargest(numArr);
        }

    很明显,测试肯定会抛出一个异常,不能通过。

   

    那现在我们知道这样输入是不对,那怎么可以屏蔽掉这个异常呢。[ExpectedException],这个实行有几个重载的类型,根据情况自己选择。

代码
        [Test]
        [ExpectedException(
typeof (Exception))]
        
public   void  TestGetLargest2()
        {
            
int [] numArr  =   new   int [] { };

            largest.GetLargest(numArr);
        }

 

    这个时候我们看到的结果不再是提示有异常抛出,而是通过了测试(你都已经预料到有这种异常了,当然不会再提示你程序会抛出这个异常!)

    六、最后简单的提一下其他几个属性:[Ignore]标识的Test Case不会再NUnitIDE中执行,因为被你忽略掉了。[Explicit]必须要显示的选中这个Case才会被执行,否则是不会执行的。[Category]分组属性,可以将几个Case分到同一个组中,这样就会以组为单位去执行,或不执行。

    测试类完整代码贴上:

代码
    [TestFixture]
    
public   class  LargestTest
    {
        
private  Largest largest;

        [SetUp]
        
public   void  InitCase()
        {
            largest 
=   new  Largest();
            Console.WriteLine(
" 我会在执行每个Test Case之前初始化对象! " );
        }

        [TearDown]
        
public   void  TerminateCase()
        {
            largest 
=   null ;
            Console.WriteLine(
" 我会在执行完每个Test Case之后销毁对象! " );
        }

        [TestFixtureSetUp]
        
public   void  Init()
        {
            largest 
=   new  Largest();
            Console.WriteLine(
" 我只会在类的最初调用时初始化对象! " );
        }

        [TestFixtureTearDown]
        
public   void  Terminate()
        {
            
if  ( null   !=  largest)
            {
                largest 
=   null ;
            }
            Console.WriteLine(
" 我只会在类的最后销毁对象! " );
        }

        [Test]
        
public   void  TestGetLargest()
        {
            
int [] numArr  =   new   int [] {  - 1 0 2 4 - 10  };

            
int  result  =  largest.GetLargest(numArr);

            Assert.AreEqual(
4 , result);
        }

        [Test]
        
public   void  TestGetLargest1()
        {
            
int [] numArr  =   new   int [] { };

            largest.GetLargest(numArr);
        }

        [Test]
        [ExpectedException(
typeof (Exception))]
        
public   void  TestGetLargest2()
        {
            
int [] numArr  =   new   int [] { };

            largest.GetLargest(numArr);
        }

        [Test]
        
public   void  TestGetLargest3()
        {
            
int [] numArr  =   new   int [] {  10 10  };
            
int  result  =  largest.GetLargest(numArr);

            Assert.AreEqual(
10 , result);
        }

        [Test]
        [Ignore]
        
public   void  TestGetLargest4()
        {
            
int [] numArr  =   null ;

            
int  result  =  largest.GetLargest(numArr);
        }
}

执行结果:

不知道有没有发现个问题,对于这个程序中,测试案例会很多,比如说数组的数全是正数,负数,有正有负,全部数相同时等等,这样不就要写很多重复的测试case,应该有其他的方法吧。呵呵,不妨试试利用XML、文本存储数据来实现。下一部分我准备用XML读取数据来实现。

你可能感兴趣的:(单元测试)