第四节:深入介绍Nunit
我们已经介绍了简单的单元测试,下面来看看各种形式的断言,以及Nunit测试的结构和组成等等
测试代码仅限于我们内部使用,最终是和产品代码分离的
测试代码必须要做以下几件事情:
准备测试所需要的各种条件
调用要测试的方法
验证与被测方法的行为和期望是否一致
完成后清理各种资源
前面我们提到了断言,她是单元测试最基本的组成部分,Nunit程序库以Assert类的静态方法的形式提供了不同形式的各种断言。
AreEqual,AreSame,Equals, Fail,Ignore,IsFalse,IsNotNull
1.AreEqual Assert.AreEqual(expected,actual[,string mssage])
expected 是你所期望的值,这个是硬代码
actual是被测代码实际产生的值
message 是可选的 提供错误报告自己定义的信息
2.IsNull Assert.IsNull(obj[, string message]) 或者Assert.IsNotNull(....)
验证给定的一个对象是否为空或者非空
3.AreSame Assert.AreSame(expected,actual[,string message])
参数与第一个含义相同
4.IsTrue Assert.IsTrue(bool condation[,string message])
验证给定的二元条件是否为真
5.Fail Assert.Fail([string message])
这个断言会使测试立刻失效,用于标记某个不应该到达的分支, 并不常用
我们测试代码时候会写好多断言,只要一个失败就必须修复失败的测试再进行测试 ,
那么我们能不能运行所有测试呢?即时里面有通过的 有没有用过的
所以我们就需要一个框架---Nunit框架
一个test fixture(也就是一个用[TextFixture]标记的类),包含一个或者多个测试方法,每个方法又包含一个或者多个断言,一个程序集可以包含多个test fixture
在GUI(Nunit软件本身,这里不对命令行等做介绍)中选择一个测试或者一个test fixture 或者整个程序集来执行测试
我们可以把这多个test fixture 组合进一个test suite中,,任何测试都可以包含一个用[Suite]属性 标记的静态方法,这个方法将返回一个TestSuite, 她就是TextFixture的一些集合

using System.Web;
using NUnit.Framework;
using NUnit.Core;
namespace WebApplication7
{
[TestFixture]
public class TextClassSuite
{
[Suite]
public static TestSuite Suite
{
get
{
TestSuite suite=new TestSuite("Name of Suite");
suite.Add(new TextClass11() );
return suite;
}
}
[TestFixture]
public class TextClass11
{
}
}
}
这里的Nunit.Core引用 我在Nunit的安装后并没有在引用的.net选择项中找到 请指教。。。。(我是找了一个dll文件添加进来的)
你添加到suite就是有TestFixture标记的类名 她可以让你给这些fixture进行分组但是并不影响测试的运行,通过运行Suite(),你就可以一次运行多个fixture了
---Nunit还提供了另一种机制,来对每个单独的测试方法和test fixture进行分门别类(Categories)
Nunit 用categories的概念提供了标记和运行一个个单独的测试和fixture的简单方法。
例如就对一个时间复杂度(数据结构中的含义)是指数增长的算法来说 可以把前期后期分开测试
例如你具有好多只需要几秒就能完成的方法,但是另有一个方法要花费很多时间去完成,你就可以用过使用分类名“Short”和“Long”来标记他们,

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using NUnit.Framework;
using NUnit.Core;
namespace WebApplication7
{
[TestFixture]
public class TextShortestpath
{
[Test]
[Category("Short")]
public void Use5cities()
{
TSP tsp = new TSP();
Assert.AreEqual(5,tsp.Shortestpath(5));
}
[Test, Category("Short")]
public void Use10citis()
{
TSP tsp = new TSP();
Assert.AreEqual(10, tsp.Shortestpath(10));
}
[Test, Category("Long")]
public void Use550cities()
{
TSP tsp = new TSP();
Assert.AreEqual(550, tsp.Shortestpath(550));
}
}
public class TSP
{
public int Shortestpath(int i)
{
return i;
}
}
}
Category 同样可以标记Test Fixture 从而进行各种分类测试了 。
为了使得测试任何时候以任何顺序独立运行
Nunit指定了两种方法分别用于环境的建立[SetUp]和清理[TearDown]
使得在调用每个[Test]方法前。调用一个[SetUp]标记的方法 ,并且在每个测试方法完成之后,调用一个[TearDown]标记的方法

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using NUnit.Framework;
using NUnit.Core;
using System.Data;
using System.Data.SqlClient;
namespace WebApplication7
{
[TestFixture]
public class TextShortestpath
{
private SqlConnection con;
[SetUp]
public void MySetup()
{
con = new SqlConnection("");
con.Open();
}
[TearDown]
public void MyTeardown()
{
con.Close();
}
[Test]
public void TestAccoutAccess()
{
}
[Test]
public void TestEmployAccess()
{
}
}
}
相同的也可以针对testfixture 对真个test class进行设置[TestFixtureSetUp][TestFixtureTearDown] 不常见
下面来介绍下软件测试中的异常
有时候我们会需要显示的获取一个异常,Nunit提供了[ExpectedException]属性
[Test,ExpectedException(typeof(ArgumentException))]
现在测试方法期望抛出一个异常。如果没有抛出,测试将失败,异常抛出,测试会通过
实际上,Nunti框架可以抛出任何异常,并且把它报告为一个错误。
临时忽略一些测试
[Ignore]Nunit提供了这个属性来告知测试被跳过了,使得测试框架不必运行这个测试
现在我们已经学会了如何编写测试了,在下面我们需要进一步介绍那些内容需要测试