NUnit 中一次性初始化的涵蓋範圍

一般來說套件的使用方式沒什麼好寫的, 但是使用 NUnit 的 OneTimeSetUp 時, 究竟是在多大的範圍做一次性的行為會根據這個特性 (Attribute) 的使用位置而不同, 這部分文件是放在 SetUpFixture Attribute 一節 說明, 不過沒有所有情境的範例程式, 所以做了一些實驗來簡單紀錄一下更細節的部分.

使用方式與範圍

OneTimeSetUp 根據所使用的位置不同, 涵蓋的範圍會不同, 主要有三種:

  • 類別層級 :
    該類別下加上 OneTimeSetUp 特性的方法只會執行一次.
  • 命名空間層級 :
    該命名空間下加上 OneTimeSetUp 特性的方法只會執行一次, 且該類別上需要加 SetUpFixture 特性, 包含子命名空間, 例如命名空間 NS 下的 OneTimeSetUp 在 NSNS.Sub 命名空間總共只會執行一次.
  • 組件層級 :
    若不在任何命名空間下, 則加上 OneTimeSetUp 特性的方法在整個組件中只會執行一次, 而該類別上也需要加 SetUpFixture 特性.

範例程式碼

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
using NUnit.Framework;
using System.Diagnostics;

[SetUpFixture]
public class OneTimeSetupClass
{
[OneTimeSetUp]
public void OneTimeSetupMethod()
{
Debug.Print($"-- Assembly wide one-time setup.");
}
}

namespace NS
{
[SetUpFixture]
public class OneTimeSetupClass
{
[OneTimeSetUp]
public void OneTimeSetupMethod()
{
Debug.Print($"-- Namespace wide one-time setup.");
}
}

[TestFixture]
public class TestClass1
{
[OneTimeSetUp]
public void OneTimeSetupMethod()
{
Debug.Print($"-- Class wide one-time setup.");
}

[Test]
public void TestMethod1()
{
Debug.Print($"Executeing NS.TestClass1.TestMethod1()");
}

[Test]
public void TestMethod2()
{
Debug.Print($"Executeing NS.TestClass1.TestMethod2()");
}
}

[TestFixture]
public class TestClass2
{
[OneTimeSetUp]
public void OneTimeSetupMethod()
{
Debug.Print($"-- Class level one-time setup 2.");
}

[Test]
public void TestMethod1()
{
Debug.Print($"Executeing NS.TestClass2.TestMethod1()");
}

[Test]
public void TestMethod2()
{
Debug.Print($"Executeing NS.TestClass2.TestMethod2()");
}
}
}

namespace NS.Sub
{
[TestFixture]
public class TestClass1
{
[Test]
public void TestMethod1()
{
Debug.Print($"Executeing NS.Sub.TestClass1.TestMethod1()");
}

[Test]
public void TestMethod2()
{
Debug.Print($"Executeing NS.Sub.TestClass1.TestMethod2()");
}
}
}

namespace NotNS
{
[TestFixture]
public class TestClass1
{
[Test]
public void TestMethod1()
{
Debug.Print($"Executeing NotNS.TestClass1.TestMethod1()");
}

[Test]
public void TestMethod2()
{
Debug.Print($"Executeing NotNS.TestClass1.TestMethod2()");
}
}
}

以上是示範程式碼, 可以從下方的輸出訊息中看出一次性行為的範圍:

1
2
3
4
5
6
7
8
9
10
11
12
-- Assembly wide one-time setup.
Executeing NotNS.TestClass1.TestMethod1()
Executeing NotNS.TestClass1.TestMethod2()
-- Namespace wide one-time setup.
Executeing NS.Sub.TestClass1.TestMethod1()
Executeing NS.Sub.TestClass1.TestMethod2()
-- Class wide one-time setup.
Executeing NS.TestClass1.TestMethod1()
Executeing NS.TestClass1.TestMethod2()
-- Class level one-time setup 2.
Executeing NS.TestClass2.TestMethod1()
Executeing NS.TestClass2.TestMethod2()

結論

因為 OneTimeSetUp 是根據所使用的位置不同而有不同的涵蓋範圍, 所以一開始有點不確定怎麼用, 就稍微寫一下簡單的筆記紀錄一下.

參考

SetUpFixture Attribute