浅述NUnit单元测试-----以为BubbleSort编写单元测试为例

  写这篇博文的目的是给大家分享,如何使用NUnit为我们的.NET应用程序编写单元测试,文章假设读者没有使用过NUnit的新手,如果你是老手,可以跳过本文。如果你对NUnit还不是很了解的话,我建议你还是阅读一下。

首先介绍几个概念。

1.NUnit的介绍

  NUnit是一个单元测试框架,专门针对于.NET来写的。其实在前面有JUnit(Java),CPPUnit(C++),他们都是xUnit的一员。最初,它是从JUnit而来.现在的版本是2.6.接下来我所用的都是基于这个版本。
  NUnit最初是由James W. Newkirk,Alexei A. Vorontsov 和Philip A. Craig,后来开发团队逐渐庞大起来.在开发过程中, Kent Beck 和Erich Gamma2位也提供了许多帮助。看来对于NUnit还真是下了一番力气了。
  NUnit是xUnit家族种的第4个主打产品,完全由C#语言来编写,并且编写时充分利用了许多.NET的特性,比如反射,客户属性等等。
  最重要的一点是它适合于所有.NET语言。如果你还没有下载,可以到http://www.nunit.org/去下载。(文件很小,大概3点几M吧)

1.1NUnit常用属性

TestFixture     

本属性标记一个类包含测试.做为一个测试的类,这个类还有一些限制:
 1.必须是Public,否则NUnit看不到它的存在.
 2.它必须有一个缺省的构造函数,否则是NUnit不会构造它.
 3.构造函数应该没有任何副作用,因为NUnit在运行时经常会构造这个类多次,如果要是构造函数有什么副作用的话,那不是乱了。

Test    

Test属性用来标记一个类(已经标记为TestFixture)的某个方法是可以测试的.
 1.测试方法必须为Public.
 2.测试方法必须没有参数.
 3.测试方法不返回任何参数.

SetUp/TearDown 

用于在测试开始时初始化,和测试后清除.标记为SetUp/TearDown 属性方法必须为public。

ExpectedException

这里是一个验证这个假设的测试.在这个属性里,你可以在执行过程中捕获你期望的异常类型.如果这个方法在没有抛出期望异常的情况下完成了,这个测试失败.使用这个属性帮助我们写程序员测试验证边界条件(Boundary Conditions).
Ignore

由于种种原因,有一些测试我们不想运行.当然,这些原因可能包括你认为这个测试还没有完成,这个测试正在重构之中,这个测试的需求不是太明确.但你有不想破坏测试,不然进度条可是红色的哟.怎么办?使用Ignore属性.你可以保持测试,但又不运行它们.

TestFixtureSetUp/TestFixtureTearDown 
有时,一组测试需要的资源太昂贵.例如,数据库连接可能是一个关键资源,在一个test fixture的每个测试中,打开/关闭数据库连接可能非常慢.这就是我在开始提到的问题.如何解决?NUnit有一对类似于前面讨论的SetUp/TearDown的属性: TestFixtureSetUp/TestFixtureTearDown.正如他们名字表明的一样,这些属性用来标记为整个test fixture初始化/释放资源方法一次的方法。例如,如果你想为所有test fixture的测试共享相同的数据库连接对象,我们可以写一个打开数据库连接的方法,标记为TestFixtureSetUp属性,编写另外一个关闭数据库连接的方法,标记为TestFixtureTearDown属性。

Explicit
本属性忽略一个test和test fixture,直到它们显式的选择执行。如果test和test fixture在执行的过程中被发现,就忽略他们。所以,这样一来进度条显示为黄色,因为有test或test fixture忽略了。
Category

对于测试来说,你有的时候需要将之分类,此属性正好就是用来解决这个问题的。

测试生命周期
  FixtureSetUp

loop:
   SetUp
     Test Method1
   TearDown
   SetUp
     Test Method2
   TearDown

end loop
FixtureTearDown

 
NUnit是在.NET进行TDD的利器。

2.TDD的简介

  测试驱动开发,英文全称Test-Driven Development,简称TDD,是一种不同于传统软件开发流程的新型的开发方法。它要求在编写某个功能的代码之前先编写测试代码,然后只编写使测试通过的功能代码,通过测试来推动整个开发的进行。这有助于编写简洁可用和高质量的代码,并加速开发过程。

  Kent Beck先生最早在其极限编程(XP)方法论中,向大家推荐“测试驱动”这一最佳实践,还专门撰写了《测试驱动开发》一书,详细说明如何实现。经过几年的迅猛发展,测试驱动开发已经成长为一门独立的软件开发技术,其名气甚至盖过了极限编程。

测试驱动开发的基本思想就是在开发功能代码之前,先编写测试代码,然后只编写使测试通过的功能代码,从而以测试来驱动整个开发过程的进行。这有助于编写简洁可用和高质量的代码,有很高的灵活性和健壮性,能快速响应变化,并加速开发过程。 

  测试驱动开发的基本过程如下: 

  ① 快速新增一个测试 

  ② 运行所有的测试(有时候只需要运行一个或一部分),发现新增的测试不能通过 

  ③ 做一些小小的改动,尽快地让测试程序可运行,为此可以在程序中使用一些不合情理的方法 

  ④ 运行所有的测试,并且全部通过 

  ⑤ 重构代码,以消除重复设计,优化设计结构 

  简单来说,就是不可运行/可运行/重构——这正是测试驱动开发的口号。 

 3.VS2010下使用NUnit 2.6编写单元测试示例

 首先,新建一个vs2010工程,我选择了控制台程序模板,为工程添加一个新的类:Calculator。累的内容为实现的一个BubbleSort排序。实现如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace NunitTestBubbleSort
{   
    public class Calculator
    {
        /// <summary>
        /// BubbleSort
        /// </summary>
        /// <param name="array"></param>
        /// <returns></returns>
        public int[] BubbleSort(int[] array)
        {
            if (array == null)
            {
                return new int[] { };
            }

            for (int i = 0; i < array.Length - 1; i++)//n-1次
              {
              bool swap = false;//标识
                for (int j = 0; j < array.Length - 1 - i; j++)//每次比较过程
                {
                    if (array[j] > array[j + 1])
                    {
                        int temp = array[j];
                        array[j] = array[j + 1];
                        array[j + 1] = temp;

                        swap = true;
                    }                  
                }
                if (!swap)
                {
                    return array;
                }
            }
            return array;
        }
        /*
         * 
         * 
         * 
         * 
         */


    }
}

 然后,我们为工程添加一个测试类:CalculatorTest。这时,我们需要添加一个引用:nunit.framework;并在CalculatorTest类中添加名称空间:using CalculatorTest,如下:

 这样我们就可以开始编写我们的测试类CalculatorTest了,做一个简单的测试case如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using NUnit.Framework;//引用这个名称空间

namespace NunitTestBubbleSort
{
    [TestFixture]
    public class CalculatorTest
    {
        [TestFixtureSetUp]
        public void FirstInit()
        { 
            //
        }
        [SetUp]
        public void Init()
        { 
            //
        }
        [TearDown]
        public void Dispose()
        { 
            //
        }
        [TestFixtureTearDown]
        public void LastDispose()
        { 
            //
        }

        [Test]
        public void BubbleSortTest()
        {
            int[] arr = new int[] { 9, 8, 77, -10, 0 };

            int[] expect=new  int[]{-10,0,8,9,77};

            Calculator ca = new Calculator();
            int[] result = ca.BubbleSort(arr);
            Assert.AreEqual(expect, result);
        }

        [Test ,Explicit ]
        public void BubbleSortTest2()
        {
            int[] arr = null;
            int[] expect = new int[] { };

            Calculator ca = new Calculator();
            int[] result = ca.BubbleSort(arr);
            Assert.AreEqual(expect, result);
        }
    }
}

然后,打开NUnit工具,Open刚生成的PE文件。RUN之。效果如下:

绿色,代表我们的测试通过。

关于NUnit的进一步讲解,请期待下集。

请点击下面的“绿色通道”----“关注DebugLZQ”,共同交流进步~

posted @ 2012-07-08 15:27  DebugLZQ  阅读(1717)  评论(1编辑  收藏  举报