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

{ 6
[TestFixtureSetUp] 7
public void OpenConnection() 8
{ 9
//open the connection to the database 10
} 11
12
[TestFixtureTearDown] 13
public void CloseConnection() 14
{ 15
//close the connection to the database 16
} 17
18
[SetUp] 19
public void CreateDatabaseObjects() 20
{ 21
//insert the records into the database table 22
} 23
24
[TearDown] 25
public void DeleteDatabaseObjects() 26
{ 27
//remove the inserted records from the database table 28
} 29
30
[Test] 31
public void ReadOneObject() 32
{ 33
//load one record using the open database connection 34
} 35
36
[Test] 37
public void ReadManyObjects() 38
{ 39
//load many records using the open database connection 40
} 41
}
42
43

























































Test Suite
Test Suite是test case或其他test suite的集合. 合成(Composite)
,模式描述了test case和test suite之间的关系.
参考来自NUnit的关于Suite的代码
Suite Attribute
1
namespace
NUnit.Tests
2
{
3
using System;
4
using NUnit.Framework;
5
6
7
8
public class AllTests
9
{
10
[Suite]
11
public static TestSuite Suite
12
{
13
get
14
{
15
TestSuite suite = new TestSuite("All Tests");
16
suite.Add(new OneTestCase());
17
suite.Add(new Assemblies.AssemblyTests());
18
suite.Add(new AssertionTest());
19
return suite;
20
}
21
}
22
}
23
}
24

2



3

4

5

6

7

8

9



10

11

12



13

14



15

16

17

18

19

20

21

22

23

24

对于测试来说,你有的时候需要将之分类,此属性正好就是用来解决这个问题的。
你可以选择你需要运行的测试类目录,也可以选择除了这些目录之外的测试都可以运行。在命令行环境里 /include 和/exclude来实现。在GUI环境下,就更简单了,选择左边工作域里的Catagories Tab,选择Add和Remove既可以了。
在上面的例子上做了一些改善,代码如下:
1
using
System;
2
using
NUnit.Framework;
3
4
namespace
NUnitQuickStart
5

{ 6
[TestFixture] 7
public class NumersFixture 8
{ 9
private int a; 10
private int b; 11
[SetUp] 12
public void InitializeOperands() 13
{ 14
a = 1; 15
b = 2; 16
} 17
18
[Test] 19
[Category("Numbers")] 20
public void AddTwoNumbers() 21
{ 22
int sum=a+b; 23
Assert.AreEqual(sum,3); 24
} 25
26
[Test] 27
[Category("Exception")] 28
[ExpectedException(typeof(DivideByZeroException))] 29
public void DivideByZero() 30
{ 31
int zero = 0; 32
int infinity = a/zero; 33
Assert.Fail("Should have gotten an exception"); 34
} 35
[Test] 36
[Ignore("Multiplication is ignored")] 37
[Category("Numbers")] 38
public void MultiplyTwoNumbers() 39
{ 40
int product = a * b; 41
Assert.AreEqual(2, product); 42
} 43
44
} 45

























































图5-2:使用Catagories属性的界面
Explicit属性
本属性忽略一个test和test fixture,直到它们显式的选择执行。如果test和test fixture在执行的过程中被发现,就忽略他们。所以,这样一来进度条显示为黄色,因为有test或test fixture忽略了。
例如:
1
2
[Test,Explicit]
3
[Category(
"
Exception
"
)]
4
[ExpectedException(
typeof
(DivideByZeroException))]
5
public
void
DivideByZero()
6
{
7
int zero = 0;
8
int infinity = a/zero;
9
Assert.Fail("Should have gotten an exception");
10
}
11

2

3

4

5

6



7

8

9

10

11

Expected Exception属性
期望在运行时抛出一个期望的异常,如果是,则测试通过,否则不通过。
参看下面的例子:
1
[Test]
2
[ExpectedException(typeofInvalidOperationException))]
3
public
void
ExpectAnException()
4
{
5
int zero = 0;
6
int infinity = a/zero;
7
Assert.Fail("Should have gotten an exception");
8
9
}
10

2

3

4



5

6

7

8

9

10

5 . 测试生命周期合约
如果记得test case的定义,其中一个属性是测试的独立性或隔离性.
SetUp/TearDown方法提供达到测试隔离性的目的.
SetUp确保共享的资源在每个测试运行前正确初始化,
TearDown确保没有运行测试产生的遗留副作用.
TestFixtureSetUp/
TestFixtureTearDown同样提供相同的目的,但是却在test fixture范围里,我们刚才描述的内容组成了测试框架的运行时容器(test runner)和你写的测试之间的生命周期合约(
life-cycle contract).
为了描述这个合约,我们写一个简单的测试来说明什么方法调用了,怎么合适调用的.这里是代码:
1
using
System;
2
using
NUnit.Framework;
3
[TestFixture]
4
public
class
LifeCycleContractFixture
5

{ 6
[TestFixtureSetUp] 7
public void FixtureSetUp() 8
{ 9
Console.Out.WriteLine("FixtureSetUp"); 10
} 11
12
[TestFixtureTearDown] 13
public void FixtureTearDown() 14
{ 15
Console.Out.WriteLine("FixtureTearDown"); 16
} 17
18
[SetUp] 19
public void SetUp() 20
{ 21
Console.Out.WriteLine("SetUp"); 22
} 23
24
[TearDown] 25
public void TearDown() 26
{ 27
Console.Out.WriteLine("TearDown"); 28
} 29
30
[Test] 31
public void Test1() 32
{ 33
Console.Out.WriteLine("Test 1"); 34
} 35
36
[Test] 37
public void Test2() 38
{ 39
Console.Out.WriteLine("Test 2"); 40
} 41
42
}
43
44


























































当编译和运行这个测试,可以在
System.Console窗口看到下面的输出:


