在單元測試的藝術提到:進行單元測試時,很重要的一點是確保之前測試過程中所遺留下來的資料或執行個體得以銷毀,新的測試執行時,狀態是重置過的,就像沒有執行過測試一般
。
換言之,單元測試之間,必須是互相獨立的,不會因第一個單元測試的參數設定而影響到其他的單元測試。所以執行測試時,執行前會做設定的動作(SetUp)與清理單元測試完的參數(TearDown)。因此,撰寫多個測試時且有共同的變數,則可以在 SetUp 和 Teardown 撰寫程式碼,如下:
[TestFixture]
public class UnitTests
{
// 新增 account 變數
private BankAccount account = null;
[SetUp]
public void Setup()
{
// 兩隻單元測試的初始化 Arrange 一致
account = new BankAccount(1000);
}
[Test]
public void Adding_Funds_Updates_Balance()
{
// Act
account.Add(500);
// Assert
Assert.AreEqual(1500, account.Balance);
}
// 第二隻單元測試,檢測提款是否符合預期
[Test]
public void Withdrawing_Funds_Updates_Balance()
{
// Act
account.Withdraw(500);
// Assert
Assert.AreEqual(500, account.Balance);
}
// 謹在此示範 TearDown 寫法,明後天完善這個 HelloBankTest 測試專案,不會撰寫這段
[TearDown]
public void TearDown()
{
// 將 account 重新設定為 null
account = null;
}
}
實務上其實大多時候 TearDown 的動作算是多此一舉;以本例來說,因為在執行完存款後,準備執行提款的測試前,會經由 Setup 把 account 重新指定新的物件。然而,在單元測試的藝術書中有提到一種情況是需要 TearDown,就是需要在測試之間「重設」一個靜態變數或單例(Singleton)的狀態。
另一方面,SetUp 可以簡化很多單元測試準備物件的程式碼(假設要驗證一百種情況,皆都是需要設定一樣的 account,則透過 SetUp 就可以精簡上百行的程式碼);但 Roy Osherove 提醒若隨著單元測試的複雜性越來越高,則可能會使得 SetUp 變成難以維護的方法之一。
使用 Ignore 忽略測試,最常見的例子為在 CI/CD 上版時發現部分測試尚未通過(但非需急迫性測試),又或是因升級版本(之前有在學 Pytest,曾遇過 Python 2 轉 Python 3 而導致測試錯誤)等等情況,需要先忽略其測試,就會需要用到 Ignore,程式碼如下:
[Test]
[Ignore("This is an example for ignore demo")]
public void Transfering_Funds_Updates_Both_Account()
{
// Nothing...
}
然後觀看測試成果,可以看到如圖: