天天看點

玩轉浏覽器自動化(8)使用 NUnit 編寫測試

作者:opendotnet

在上一章中,我們編寫了一個簡單的測試,現在我們需要更深入地了解 NUnit 測試代碼的細節,包括測試代碼的結構群組成,NUnit 斷言的不同形式等等。

測試代碼的結構

讓我們回顧一下上一篇中的測試代碼,它展示了我們需要的最小結構:

using Microsoft.Playwright;

namespace TestProject1
{
[TestFixture]
public class Tests
{
[Test]
public async Task NavigateToBaidu_TitleIsIsCorrect()
{
var playwright = await Playwright.CreateAsync();

 await using var browser = await playwright.Chromium.LaunchAsync(); 

 var page = await browser.NewPageAsync(); 

 await page.GotoAsync("https://www.baidu.com"); 

 var title = await page.InnerTextAsync("title"); 

 Assert.That(title, Is.EqualTo("百度一下,你就知道")); 
 } 
} 
}
           

首先,每個包含測試的類都必須使用 [TestFixture] 特性進行聲明。類必須聲明為 public,并且必須有一個公共的、無參數的構造函數,否則 NUnit 無法識别測試類。通常情況下,我們不需要手動添加構造函數,因為預設的隐式構造函數已經滿足了這個要求。

接下來,我們需要聲明一個或多個測試方法。任何使用 [Test] 特性聲明的公共、無參數的方法都将作為測試方法被 NUnit 自動運作。測試方法必須傳回 void 或 Task,因為 Playwright 測試方法都是異步的,是以我們必須使用 async 修飾符。我們也可以在測試中包含其他輔助方法,隻需不将它們标記為測試方法即可。

測試方法的命名沒有任何限制,但我們建議使用有意義的名稱,比如 NavigateToBaidu_TitleIsIsCorrect。這樣做的好處是,當測試失敗時,我們可以很容易地找到它所對應的測試方法。描述性的方法名稱可以幫助測試者快速識别測試用例的用途。名稱應簡潔、明确且一緻,我們建議使用以下命名規則:

  • 使用動詞開頭,比如 Navigate、Click、Fill 等等。
  • 描述測試用例的目的,比如 NavigateToBaidu。
  • 描述測試用例的期望結果,比如 TitleIsCorrect。

最後,在每個測試方法中,我們需要編寫測試代碼來驗證我們的程式是否按照預期運作。通常,測試代碼遵循一個标準的公式,稱為 Arrange-Act-Assert(AAA)模式:

  • 準備(Arrange):設定測試所需的所有條件,包括建立必要的對象和配置設定必要的資源等。
  • 執行(Act):調用要測試的方法。
  • 斷言(Assert):驗證是否得到了預期的結果。

AAA模式将測試代碼分為三個明确的部分,每個部分都有特定的目的。通過遵循這種結構,測試代碼更加簡潔、易于編寫和管理,也更容易閱讀和了解。測試代碼不僅能夠證明功能有效,還能示範功能或元件的工作原理,這樣無需文檔,也能清楚地說明功能的工作原理。此外,AAA模式也有助于調試,因為每個測試都是一個隔離的單元,當測試失敗時,可以更容易地定位問題所在。

例如,在上一章中,我們可以将AAA模式應用到測試代碼中:

[Test]
public async Task NavigateToBaidu_TitleIsIsCorrect()
{
// 準備
var playwright = await Playwright.CreateAsync();
await using var browser = await playwright.Chromium.LaunchAsync();
var page = await browser.NewPageAsync();

// 執行 
await page.GotoAsync("https://www.baidu.com"); 

// 斷言 
var title = await page.InnerTextAsync("title"); 
Assert.That(title, Is.EqualTo("百度一下,你就知道")); 
}
           

通過遵循AAA模式,我們可以更加清晰地分離測試的不同部分,并使測試代碼更加易于閱讀、了解和維護。

斷言

在使用 NUnit 進行測試時,我們需要使用斷言來驗證測試結果是否符合預期。斷言是一種驗證測試結果的方法,可以是簡單的比較,也可以是複雜的邏輯。如果斷言失敗,測試也将失敗。

NUnit 提供了一組斷言方法,用于比較預期和實際結果。其中,推薦使用以下斷言方法:

Assert.That<TActual>(TActual actual, IResolveConstraint expression) 
           

該方法接受兩個參數,第一個參數是實際的結果,第二個參數是一個斷言表達式。斷言表達式可以是一個簡單的比較,也可以是一個複雜的邏輯表達式。以下是一些常用的斷言表達式:

  • Is.EqualTo(expected):判斷實際結果是否等于預期結果,例如 Assert.That(1 + 2, Is.EqualTo(3))。可以在任何 Is 斷言表達式中間添加 Not,以表示原始表達式的否定,例如 Assert.That(1 + 2, Is.Not.EqualTo(4))。
  • Is.AtMost(expected):判斷實際結果是否小于或等于預期結果,例如 Assert.That(1 + 2, Is.AtMost(4))。
  • Is.AtLeast(expected):判斷實際結果是否大于或等于預期結果,例如 Assert.That(1 + 2, Is.AtLeast(3))。
  • Is.:判斷實際結果是否為 ,例如 Assert.That(anObject, Is.)。
  • Is.Empty:判斷實際結果是否為空集合或字元串,例如 Assert.That(aString, Is.Empty)。

Setup/TearDown

使用 Playwright for NET 進行單元測試時,除了 Arrange-Act-Assert 這個标準公式,還需要進行事後清理。因為每個測試都應該是互相獨立的,這樣才能在任何時間以任何順序運作任何單個測試。為了實作這個目标,你可能需要在測試之前重置測試環境,或在測試之後進行清理工作,以確定測試之間的環境隔離。比如,為每個測試建立一個新的浏覽器對象,或在測試之後關閉浏覽器對象。

為了實作這個目标,你可以使用 [SetUp] 特性來辨別一個方法,在每個測試方法運作之前運作。你還可以使用 [TearDown] 特性來辨別一個方法,在每個測試方法運作之後運作。通過這種方式,你可以在測試之前進行初始化工作,以及在測試之後進行清理工作。以下是一個示例:

[SetUp]
public void Setup()
{
// 進行初始化工作
}

[Test]
public void TestMethod1()
{
// 執行測試方法 1
}

[Test]
public void TestMethod2()
{
// 執行測試方法 2
}

[TearDown]
public void TearDown()
{
// 進行清理工作
}
           

在上面的示例中,每次運作測試時,都會先調用 Setup 方法進行初始化工作,然後執行測試方法 1 或測試方法 2,最後再調用 TearDown 方法進行清理工作。這樣就可以確定每個測試都是互相獨立的,并且可以在任何時間以任何順序運作任何單個測試。

如何運作測試?

在軟體測試中,我們可能需要運作所有的測試,也可能隻需運作某個測試類或某個測試方法。在上一章中,我們已經介紹了如何使用指令行運作測試。在這一章中,我們将介紹如何使用 Visual Studio 運作測試。

玩轉浏覽器自動化(8)使用 NUnit 編寫測試

在 Visual Studio 中,可以使用測試資料總管運作測試。測試資料總管是一個新的 Visual Studio 視窗,它顯示了解決方案中的所有測試。可以在 Visual Studio 的菜單欄中找到測試資料總管,選擇“測試”->“測試資料總管”。

在測試資料總管中,隻需點選視窗上方的“運作”按鈕,就可以運作所有測試。當測試執行完畢後,可以看到每個測試的執行時間,還會顯示測試的執行結果。如果測試執行成功,那麼測試将顯示綠色的對勾。如果測試執行失敗,那麼測試将顯示紅色的叉。如果測試執行失敗,可以通過單擊測試來檢視失敗的原因。

如果要運作單個測試,可以選擇測試資料總管中的測試(也可以選擇多個測試),然後單擊滑鼠右鍵,在彈出菜單中單擊“運作”。

如何過濾測試?

如果需要選擇滿足特定條件的測試,例如隻運作“張三”編寫的測試方法,這時我們就需要過濾測試。

你可以将一個或多個 [Category] 特性和不同的測試方法相關聯,然後在運作測試時選擇要包括哪些類别。這個特性可以幫助你更加靈活地管理和運作測試。

玩轉浏覽器自動化(8)使用 NUnit 編寫測試

但是有時候你需要運作同時滿足多個類别的測試方法,就需要使用測試資料總管右邊的“搜尋篩選器”。例如,如果要運作同時滿足“Short”和“Night”類别的測試方法,那麼就需要在“搜尋篩選器”中輸入“Trait:"Short" Trait:"Night"”。當然,你也可以在“搜尋篩選器”中輸入其他條件進行過濾,例如,你可以輸入“FullName:"Method2"”來篩選出所有名稱中包含“Method2”的測試方法。這個特性可以幫助你更加準确地運作測試。

如果你是使用指令行運作測試,可以使用“--filter”參數來指定過濾測試。例如,要運作同時滿足“Short”和“Night”類别的測試方法,可以使用下面的指令:

dotnet test --filter "Category = Short & Category = Night" 
           

總結

為了更好地進行測試,我們需要學習 NUnit 架構的基本使用方法。在本章中,我們已經了解了 NUnit 架構的基本結構和常用的斷言方法。

在下一章中,我們将進一步學習如何使用 Playwright 的測試基類來編寫 Playwright 測試,這将讓我們的測試更加高效和簡便。

繼續閱讀