1、初识NUnit
NUnit是一个开源单元测试框架,它提高一套API,同时拥有自己的GUI,如下:
2、NUnit常用属性
(1)TestFixture:这个属性标记一个类是测试用例类,也就是说NUnit根据这个数据判断一个类是否是测试类。当然,NUnit对测试类也是有要求的:类必须是Public的;必须有一个默认的构造函数;默认的构造函数不应该有任何副作用。引用个例子如下:
using System;
using NUnit.Framework;
[TestFixture]
public class PriceFixture
{
//...
}
(2)Test:这个属性用来标记一个类(已经标记为TestFixture)的某个方法是可以测试的,同样NUnit对可测试Method也有一定要求:为了和先前的版本向后兼容,头4个字符(“test”)忽略大小写;这个方法必须没有任何参数;这个方法没有任何返回值;这个方法为Public的。引用个例子如下:
using System;
using NUnit.Framework;
[TestFixture]
public class SuccessTests
{
[Test]
public void Test1()
{//TODO:}
}
一般来说,有了上面两个属性,你可以做基本的事情了,但对于一个真正的测试来说这还不够,有可能还需要下面的属性配合工作。
(3)SetUp/TearDown:在早期给的test fixture定义里,我们说test fixture的测试是一组常规运行时资源.在测试完成之后,或是在测试执行种,或是释放或清除之前,这些常规运行时资源在一确定的方式上可能需要获取和初始化.NUnit使用2个额外的属性:SetUp 和TearDown,就支持这种常规的初始化/清除.我们上面的例子来描述这个功能.让我们增加乘法.
[TestFixture]
public class NumersFixture{
[Test]
public void AddTwoNumbers(){
int a=1;
int b=2;
int sum=a+b;
Assert.AreEqual(sum,3);
}
[Test]
public void MultiplyTwoNumbers(){
int a=1;
int b=2;
int product = a * b;
Assert.AreEqual(2, product);
}
}
我们仔细一看,不对,有重复的代码,如何去除重复的代码呢?我们可以提取这些代码到一个独立的方法,然后标志这个方法为SetUp 属性,这样2个测试方法可以共享对操作数的初始化了,这里是改动后的代码:
[TestFixture]
public class NumersFixture{
private int a;
private int b;
[SetUp]
public void InitializeOperands(){
a = 1;
b = 2;
}
[Test]
public void AddTwoNumbers(){
int sum=a+b;
Assert.AreEqual(sum,3);
}
[Test]
public void MultiplyTwoNumbers(){
int product = a * b;
Assert.AreEqual(2, product);
}
}
这样NUnit将在执行每个测试前执行标记SetUp属性的方法.在本例中就是执行InitializeOperands()方法.记住,这里这个方法必须为public,不然就会有以下错误:Invalid Setup or TearDown method signature
(4)ExpectedException: 有的时候,我们知道某些操作会有异常出现,这个属性帮助我们写程序员测试验证边界条件。引用例子如下:
[Test]
[ExpectedException(typeof(DivideByZeroException))]
public void DivideByZero(){
int zero = 0;
int infinity = a/zero;
Assert.Fail("Should have gotten an exception");
}
DivideByZero方法有另外一个客户属性: ExpectedException.在这个属性里,你可以在执行过程中捕获你期望的异常类型,例如在本例就是DivideByZeroException.
(5)Ignore: 由于种种原因,有一些测试我们不想运行。但你有不想破坏测试,此时使用Ignore属性。你可以保持测试,但又不运行它们。引用例子如下:
[Test]
[Ignore("Multiplication is ignored")]
public void MultiplyTwoNumbers(){
int product = a * b;
Assert.AreEqual(2, product);
}
被Ignore后,运行包含这个用例的测试,会出现红色标记,如下图:
Ignore属性可以附加到一个独立的测试方法,也可以附加到整个测试类(TestFixture).如果Ignore属性附加到TestFixture,所有在fixture的测试都被忽略。
(6)TestFixtureSetUp/TestFixtureTearDown:有时,一组测试需要的资源太昂贵.例如,数据库连接可能是一个关键资源,在一个test fixture的每个测试中,打开/关闭数据库连接可能非常慢.这就是我在开始提到的问题.与SetUp/TearDown的属性不同,TestFixtureSetUp和TestFixtureTearDown.正如他们名字表明的一样,这些属性用来标记为整个test fixture初始化/释放资源方法一次的方法。引用例子如下:
[TestFixture]
public class DatabaseFixture{
[TestFixtureSetUp]
public void OpenConnection(){
//open the connection to the database
}
[TestFixtureTearDown]
public void CloseConnection(){
//close the connection to the database
}
[SetUp]
public void CreateDatabaseObjects(){
//insert the records into the database table
}
[TearDown]
public void DeleteDatabaseObjects(){
//remove the inserted records from the database table
}
[Test]
public void ReadOneObject(){
//load one record using the open database connection
}
[Test]
public void ReadManyObjects(){
//load many records using the open database connection
}
}
(7)Suite: Test Suite是test case或其他test suite的集合. 合成模式描述了test case和test suite之间的关系。引用例子如下:
public class AllTests{
[Suite]
public static TestSuite Suite{
get{
TestSuite suite = new TestSuite("All Tests");
suite.Add(new OneTestCase());
suite.Add(new Assemblies.AssemblyTests());
suite.Add(new AssertionTest());
return suite;
}
}
}
(8)Category: 对于测试来说,你有的时候需要将之分类,此属性正好就是用来解决这个问题的。
你可以选择你需要运行的测试类目录,也可以选择除了这些目录之外的测试都可以运行。在命令行环境里 /include 和/exclude来实现。在GUI环境下,就更简单了,选择左边工作域里的Catagories Tab,选择Add和Remove既可以了。就不引用例子了。