C#也有测试工具-NUnit

本文通过一个银行账户类的实例,展示了如何使用NUnit进行单元测试。包括测试类的组织方式、测试方法的编写、断言的使用及异常测试等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

        NUnit,第一眼让我想起来的名词是“单元测试”,是软件工程中的一个重要部分。测试的重要性的论述到处都是,种类当然也有很多。
       测试真的只能是代码、软件的Bug Detector吗?当然原理上将就是找错,但在功用上讲,测试不仅可以作为“后期创作”的工具,如果将其运用于“前期准备”、“制作过程”中,也是一件利器。在TDD开发中,就显示了测试的重要性,以测试作为驱动力,结合设计,那是相当NB。
        理论的东西看多了,没有实践就觉得虚。这段时间用C#开发,纯粹老土的人工测试,想想Java有JUnit(只是知道,也没用过,原来不大重视),C#用什么测呢?桌面应用又该怎么测呢?
        于是乎,搜吧!这不,找到了NUnit,还是基于C#开源的,习之...

        

        NUnit是一个为Net准备的自动化单元测试框架,它的作用就是帮助你方便的完成单元测试工作,同鼎鼎有名的JUnit一样,都是xUnit家族的成员。它的下载地址是:http://www.nunit.org

        详细的语法、功能,在网站上都有,我就不画蛇添足了,下面列出我写的例子,试验一下:
Account.cs

 

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. namespace Bank
  5. {
  6.     /// <summary>
  7.     /// 银行帐户
  8.     /// </summary>
  9.     public class Account
  10.     {
  11.         /// <summary>
  12.         /// 帐户余额
  13.         /// </summary>
  14.         private float _balance;
  15.         /// <summary>
  16.         /// 帐户最小余额
  17.         /// </summary>
  18.         private float _minBalance = 10.00f;
  19.         
  20.         /// <summary>
  21.         /// 获取帐户余额
  22.         /// </summary>
  23.         public float Balance
  24.         {
  25.             get { return _balance; }
  26.         }
  27.         /// <summary>
  28.         /// 获取帐户最小余额
  29.         /// </summary>
  30.         public float MinBalance
  31.         {
  32.             get { return _minBalance; }
  33.         }
  34.         /// <summary>
  35.         /// 提款
  36.         /// 
  37.         /// </summary>
  38.         /// <param name="amount"></param>
  39.         /// <returns></returns>
  40.         public void WithDraw(float amount)
  41.         {
  42.             if (_balance - amount < MinBalance)
  43.                 throw new InsufficientMemoryException();
  44.             _balance -= amount;
  45.         }
  46.         /// <summary>
  47.         /// 存款
  48.         /// </summary>
  49.         /// <param name="amount"></param>
  50.         public void Deposit(float amount)
  51.         {
  52.             _balance += amount;
  53.         }
  54.         /// <summary>
  55.         /// 转帐
  56.         /// 如果源帐户余额不足,触发异常
  57.         /// </summary>
  58.         /// <param name="destination"></param>
  59.         /// <param name="amount"></param>
  60.         /// <exception cref="Bank.InsuficientFundsException">转帐时帐户余额不足,抛出余额不足异常</exception>
  61.         public void TransferFunds(Account destination, float amount)
  62.         {
  63.             if (_balance - amount < MinBalance)
  64.                 throw new InsufficientMemoryException();
  65.             destination.Deposit(amount);
  66.             WithDraw(amount);
  67.         }
  68.     }
  69.     public class InsuficientFundsException : ApplicationException
  70.     {
  71.     }
  72. }

AccountTest.cs

 

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using NUnit.Framework;
  5. using NUnit.Framework.SyntaxHelpers;
  6. namespace Bank
  7. {
  8.     [TestFixture]
  9.     public class AccountTest
  10.     {
  11.         private Account source;
  12.         private Account destination;
  13.         /// <summary>
  14.         /// <list type="bullet">
  15.         ///     <listheader>
  16.         ///         <term>Account</term>
  17.         ///         <description></description>
  18.         ///         <term>Init balance</term>
  19.         ///         <description></description>
  20.         ///     </listheader>
  21.         ///     <item>
  22.         ///         <term>source</term>
  23.         ///         <term>200.00</term>
  24.         ///         <term>destination</term>
  25.         ///         <term>150.00</term>
  26.         ///     </item>
  27.         /// </list>
  28.         /// </summary>
  29.         [SetUp]
  30.         public void Init()
  31.         {
  32.             source = new Account();
  33.             source.Deposit(200.00f);
  34.             destination = new Account();
  35.             destination.Deposit(150.00f);
  36.         }
  37.         /// <summary>
  38.         /// 成功存款测试
  39.         /// </summary>
  40.         [Test]
  41.         [Category("Deposit"), Description("成功存款测试")]
  42.         public void Deposit()
  43.         {
  44.             source.Deposit(100.00f);
  45.             // Assert.AreEqual(300.00f, source.Balance);
  46.             // Assert.That(300.00f, Is.EqualTo(source.Balance));
  47.             Assert.That(300.00f == source.Balance);
  48.         }
  49.         /// <summary>
  50.         /// 成功取款测试
  51.         /// </summary>
  52.         [Test]
  53.         [Category("WidthDraw")]
  54.         public void WidthDraw()
  55.         {
  56.             source.WithDraw(100.00f);
  57.             // Assert.AreEqual(100.00f, source.Balance);//, "成功取款"
  58.             Assert.That(100.00f, Is.EqualTo(source.Balance));
  59.         }
  60.         /// <summary>
  61.         /// 取款余额不足测试
  62.         /// </summary>
  63.         [Test]
  64.         [Category("WidthDraw")]
  65.         [ExpectedException(typeof(InsufficientMemoryException))]
  66.         public void WithDrawWithInsuficientFunds()
  67.         {
  68.             source.WithDraw(300.00f);
  69.         }
  70.         /// <summary>
  71.         /// 成功转帐测试
  72.         /// </summary>
  73.         [Test]
  74.         [Category("TransferFunds")]
  75.         public void TransferFunds()
  76.         {
  77.             source.TransferFunds(destination, 150.00f);
  78.             // Assert.AreEqual(50.00f, source.Balance);//, "成功转出{0},剩余{1}", 150.00f, source.Balance
  79.             // Assert.AreEqual(300.00f, destination.Balance);     
  80.        
  81.             Assert.That(50.00f, Is.EqualTo(source.Balance));
  82.             Assert.That(300.00f, Is.EqualTo(destination.Balance));
  83.         }
  84.         /// <summary>
  85.         /// 转帐余额不足测试
  86.         /// </summary>
  87.         [Test]
  88.         [Category("TransferFunds")]
  89.         [ExpectedException(typeof(InsufficientMemoryException))]
  90.         public void TransferWithInsufficientFunds()
  91.         {
  92.             source.TransferFunds(destination, 300);
  93.         }
  94.         /// <summary>
  95.         /// 转帐余额不足原子性测试
  96.         /// </summary>
  97.         [Test]
  98.         [Category("TransferFunds")]
  99.         [Ignore("Decide how to implements transaction management.")]
  100.         public void TransferWithInsufficientFundsAtomicity()
  101.         {
  102.             try
  103.             {
  104.                 source.TransferFunds(destination, 300);
  105.             }
  106.             catch
  107.             {
  108.                 // 转帐异常,原帐户金额不变
  109.             }
  110.             //Assert.AreEqual(200, source.Balance);
  111.             //Assert.AreEqual(150, destination.Balance);
  112.             Assert.That(200.00f, Is.EqualTo(source.Balance));
  113.             Assert.That(150.00f, Is.EqualTo(destination.Balance));
  114.         }
  115.         [Test]
  116.         public void DirectlyFail()
  117.         {
  118.             Assert.Fail("Directly fail");
  119.         }
  120.     }
  121. }

        为测试对象建立工程,一般是每个工程建立一个测试工程,测试工程中每个测试类对应一个需要测试的类,namespace也与其一致。这些是我想的习惯,这样比较容易理解,而且测试时的调用方法就可以作为其使用说明了。
        将需要测试的工程,要求是类库,但我想估计exe工程也行,生成输出结果,添加引用到测试工程。
       

        每个测试类由[TestFixture]标记,要求是public,有无参默认构造函数;
        每个需要运行的测试方法由[Test]标记,要求返回void,无参;
        测试就是进行一个断言判断,提供希望的到的结果、调用测试的业务逻辑,还可以提供测试结果描述信息,当运行时,结果只有成功与失败,当然还有一种情况是:抛出异常(可能是成功或失败,要看是否[ExpectedException(typeof())]了);
        在众多的测试方法中,可能存在重复的初始化代码部分,当然可以Move to a method(重构的一种方法),然后调用。NUnit也提供了[SetUp]标记的方法,实现该功能,在每次运行测试方法时自动调用该方法,这样就不用你在测试方法中调用了,方便多了;
        同[SetUp],还有[TearDown],功能差不多,只是在每次运行测试方法后执行。
        有一个很好的标记[Ignore()],可以将未实现的测试方法标记起来,每次运行的时候不运行该方法,并且不计入运行结果中。这样可以将想到,但没有实现的测试保存下来,能提醒自己。
        

        好了就简单介绍这些了。

        上面讲的NUnit是一个独立的工具,如果在开发过程中进行测试,需要来回切换,比较麻烦。不怕,有神人把它做成了VS IDE的插件,不仅提供NUnit,而且还有MbUnit, NCover, NCoverExplorer, Reflecter, TypeMock。超强!!!它就是TestDriven.NET。官方网站http://www.testdriven.net/default.aspx

 

        好了,现在C#也有测试工具了,不愁了,好好用吧~~~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值