共用方式為


配置並使用 Live 單元測試

在開發應用程式時,Live 單元測試會自動在背景執行受影響的單元測試,並即時呈現結果與程式碼覆蓋範圍。 當你修改程式碼時,即時單元測試會回饋你的變更如何影響現有測試,以及你新增的程式碼是否被一個或多個現有測試覆蓋。 這些回饋提醒你在修正錯誤或新增功能時,要撰寫單元測試。

當你使用即時單元測試來進行測試時,它會持續保存關於測試狀態的資料。 使用持久化資料讓即時單元測試能在動態執行測試時,因應程式碼變更提供卓越的效能。

Live 單元測試僅在 Visual Studio 企業版中提供,適用於針對 .NET Core 或 .NET Framework 的專案。

支援的測試框架

即時單元測試可搭配下表中三個熱門單元測試框架運作。 同時也展示了他們支援的最低版本的介面卡與框架。 單元測試框架皆可從 NuGet.org 取得。

測試架構 Visual Studio 適配器最低版本 Framework 最小版本
xUnit.net xunit.runner.visualstudio 版本 2.2.0-beta3-build1187 xunit 1.9.2
NUnit NUnit3TestAdapter 版本 3.5.1 NUnit 版本 3.5.0
MSTest MSTest.TestAdapter 1.1.4-preview MSTest.TestFramework 1.0.5-preview

如果你有較舊的基於 MSTest 的測試專案,參考 了 Microsoft.VisualStudio.QualityTools.UnitTestFramework,且不想換成較新的 MSTest NuGet 套件,建議升級到 Visual Studio 2019 或 Visual Studio 2017。

在某些情況下,你可能需要明確地還原專案參考的 NuGet 套件,即時單元測試才能運作。 您有兩個選擇:

  • 透過明確建置解決方案來還原。 在 Visual Studio 頂層選單中選擇 「建置>重建解決方案 」。
  • 在解決方案中還原套件。 右鍵點選解決方案,選擇 還原 NuGet 套件

Configure

當你第一次啟動解決方案的即時單元測試時,設定精靈會讓你設定即時單元測試應該如何建置和執行測試。

當即時單元測試停止時,你也可以透過「 測試>即時單元測試>配置即時單元測試以求解決方案」來開啟設定精靈。

當 Live 單元測試執行時,會建立一個工作區,該工作區是原始儲存庫的副本。 Live 單元測試接著會將你在 Visual Studio 中未儲存的變更套用到工作區,執行建置、測試跑,並回報最新的程式碼覆蓋情況。

你首先應該透過精靈設定檔案的複製來源和複製地點。

顯示 Live 單元測試設定精靈第 1 頁的截圖。

儲存庫根

儲存庫根會指定將被複製的資料夾,以建立 Live Unit Test 工作區。 它應該是儲存庫的根目錄,也就是說,應該包含所有原始碼、二進位檔和工具。 若解決方案檔案不在儲存庫根目錄下,可能需要更改儲存庫根目錄。

工作區根

工作區根會指定 Live Unit Testing 存放該倉庫複製品的資料夾。 請注意顯示路徑過長的例外情況。 預設情況下,根節點會建立在你的主資料夾下。 不過舉例來說,如果你通常需要在 C 磁碟建立儲存庫,工作區根目錄可以調整成像 C:\lut\Repo

指定排除的檔案

並非所有檔案都應該複製到 Live Unit Test 工作區。 在建置過程中產生的任何產物都應該被排除在複製之外,這樣一般建置就不會干擾 Live Unit Test 建置。 另外,一般 nuget restore 指令不應該干擾 Live Unit Testing nuget restore 指令。

預設情況下,Live 單元測試會排除以下兩種檔案模式之一:

  • 對於 Git 倉庫, gitignore 檔案中指定的檔案不會被複製到 Live 單元測試工作區。
  • 對於非 Git 軟體庫,基本的資料夾清單,如 bin/obj/,不會被複製到 Live Unit Testing 工作區。

對於較複雜的儲存庫,你可能需要指定自己的忽略檔案。 從精靈中選擇「<自訂>」選項。 選擇 「下一步」後,Live 單元測試在你完成精靈後建立的自訂忽略檔案內容就會出現。 是 lutignore 檔案。

備註

有些 Git 倉庫需要自訂的 lutignore 檔案,這是因為可以將即使被 gitignore 檔案忽略的文件也簽入 Git 倉庫。 如果沒有自訂 的 lutignore 檔案,Live Unit Testing 就無法複製這些檔案,這可能會導致建置失敗。

Lutignore 檔案結構

lutignore 檔案使用與 gitignore 檔案相同的格式。 它應該包含與建置過程中產生的資料夾或檔案相符的規則,避免被複製到工作區。 對於大多數預設專案範本,以下忽略檔案即可:

[Bb]in
[Oo]bj
# WILL NOT COPY ANY BIN AND OBJ FOLDERS TO THE LIVE UNIT TESTING WORKSPACE

如果你的倉庫只有一個建置資料夾,忽略檔案應該會列出該資料夾:

[Aa]rtifacts/
# WILL NOT COPY THE ARTIFACTS FOLDER TO THE LIVE UNIT TESTING WORKSPACE

如果你的資料庫在建構資料夾中包含其他工具,這些工具應該被排除在相符模式集合中:

[Aa]rtifacts/
![Aa]rtifacts/tools/
# WILL NOT COPY THE ARTIFACTS FOLDER TO THE LIVE UNIT TESTING WORKSPACE
# HOWEVER IT WILL COPY THE TOOLS SUBFOLDER THAT MIGHT CONTAIN TOOLS AND UTILITIES

建造選項

精靈設定頁面的第二部分是你設定建置選項的地方:

  • 產生 PDB:為了加快建置速度,Live Unit Test 不會在建置時產生 PDB。 這些符號檔案使您能夠在測試失敗時檢視堆疊追蹤資訊。
  • 使用多個 CPU 核心建置:預設情況下,Live 單元測試會使用多個 CPU 核心來執行建置,從而提升建置時間。 如果你的機器變慢,或是用多處理器無法建立解決方案,就不要選擇這個選項。

測試運行選項

精靈設定頁面的最後部分是設定測試執行選項的地方:

  • 測試案例逾時:有些測試可能需要很長時間才能執行。 設定此欄位時,若任何測試超過特定時間,則自動中止執行。 考試可以自動取消。
  • 使用多個處理器:預設情況下,即時單元測試會嘗試使用多個處理器來加速執行效能。 如果你的機器變慢或解決方案無法平行執行測試,就不要選擇這個選項。 例如,當多個測試嘗試從相同的檔案路徑寫入/讀取時,可能會發生這種情況。

更多配置

透過在 Visual Studio 頂層選單列選擇 工具>選項 來設定即時單元測試。

選項 面板中,展開 「所有設定>測試>即時單元測試 」區塊。

顯示 Live 單元測試設定選項的截圖。

選項 對話框中,展開 「即時單元測試>通用 」區塊。

顯示 Live 單元測試設定選項的截圖。

啟用即時單元測試(參見 啟動、暫停及停止即時單元測試)後,您可以選擇「 測試>即時單元測試>選項」再次開啟選項。

可配置選項包括:

  • 當解決方案建置並除錯時,Live 單元測試是否會暫停。

  • 當系統電池電量低於指定門檻時,Live 單元測試是否會暫停。

  • 能夠刪除所有持久化的資料。 當即時單元測試表現不可預測或意外,暗示持久化資料損壞時,此功能非常有用。

  • 即時單元測試程序能佔用的最大記憶體量。

  • 寫入即時單元測試 輸出 視窗的資訊層級。

    選項包括無日誌記錄(無日誌)、僅錯誤訊息(錯誤)、錯誤與資訊訊息(資訊,預設),或全細節(冗長)。

    你也可以透過在即時單元測試輸出視窗中,將一個使用者層級環境變數設為1 來顯示詳細輸出。 然後重新啟動 Visual Studio。

    若要將 Live Unit Testing 的詳細 MSBuild 日誌訊息擷取到檔案中,請將使用者層級的環境變數設定 LiveUnitTesting_BuildLog 為包含該日誌的檔案名稱。

自訂你的建置版本以支援即時單元測試

對於更複雜的解決方案,可能需要進一步客製化配置。 例如,測試時可能不需要建立翻譯檔案。 為了加快建置速度,你可以用 Live Unit Test 停用轉譯檔建置。 你可以透過操作專案檔案來達成這個目標。

新增即時單元測試覆寫

如果你的解決方案需要自訂步驟來建置儀表(即時單元測試),而這些步驟在「一般」非儀表化建置中並非必需,你可以在專案或 .targets 檔案中加入程式碼,檢查 BuildingForLiveUnitTesting 屬性並執行建置前後的自訂步驟。

例如,你可以寫以下範例,新增另一個僅用於即時單元測試的目標:

<Target Name="GenerateNuGetPackages" BeforeTargets="AfterBuild" Condition="'$(BuildingForLiveUnitTesting)' == 'true'">
    <Exec Command='"$(MSBuildThisFileDirectory)..\tools\GenPac" '/>
</Target>

你可以用這個 BuildingForLiveUnitTesting 屬性來停用一些不該執行的測試建置任務。 例如,即時單元測試會設定 <RunAnalyzers>false</RunAnalyzers> 停用測試分析器。

即時單元測試相依關係

有可能並非所有執行測試所需的檔案都被複製。 Live Unit Testing 會建立一個獨立的資料夾來執行測試。 這種安排允許在測試執行時進行建置,但並非所有建置資料夾的檔案都會複製到測試資料夾。

通常,您會基於以下兩個原因之一來新增測試相依性:

  • 你的測試依賴於來源樹下的檔案。 例如,測試會檢查 resx 檔案的內容,或是讀取一些設定檔。
  • 你的測試依賴於其所引用的某些函式庫。 舉例來說,一個測試執行了一個作為依賴項的可執行檔。

備註

測試相依必須存在於設定精靈中指定的 Repository Root 目錄中。

在這兩種情況下,Live 單元測試預設不會複製這些檔案,目的是為了減少執行測試時需要複製的檔案數量。 如果測試需要這些檔案,就必須用屬性 LiveUnitTestingTestDependency 明確指定。 舉例來說,假設我們有以下的佈局:

SRC/
  CONSOLE_UTILITY/
  TEST_PROJECT/
ARTIFACTS/
  CONSOLE_UTILITY/NET472/DEBUG/
  TEST_PROJECT/NET472/DEBUG/

預設情況下,當你用 Live Unit Test 建置這些專案時,它只會複製 Artifacts/Test_Project 到 test 資料夾。 若要將來源或console_utility加入測試資料夾,請將以下範例加入 test_project.csproj

<LiveUnitTestingTestDependency Include=”$(RepoRoot)/Src/ConsoleUtility” />
<LiveUnitTestingTestDependency Include=”$(RepoRoot)/Artifacts/ConsoleUtility/net472/$(Configuration)/</LiveUnitTestingTestDependency” />

開始、暫停、停止

要啟用即時單元測試,請在 Visual Studio 頂層選單中選擇「 測試>即時單元測試>開始 」。 啟用即時單元測試時,即時 單元測試 選單上的選項會從單一項目「 開始」變成 「暫停 」和 「停止」:

  • 暫停 會暫時暫停即時單元測試。

    當即時單元測試暫停時,編輯器中不會顯示覆蓋率視覺化,但所有收集的資料都會被保留。 要繼續即時單元測試,請在即時單元測試選單中選擇繼續。 即時單元測試會完成必要的工作,追蹤暫停期間所做的所有編輯,並適當更新字形。

  • 停止 會完全停止即時單元測試。 即時單元測試會丟棄所有收集到的資料。

如果你在不包含單元測試專案的解決方案中啟動即時單元測試,暫停與停止選項會出現在即時單元測試選單中,但即時單元測試並未啟動。 輸出視窗顯示一則訊息,開頭寫著:「本解決方案不參考任何支援的測試介面卡......」。

你隨時都可以暫時暫停或完全停止即時單元測試。 例如,如果你正在重構中,且知道測試會有一段時間無法正常運作,你可能會考慮採取此類措施。

包含與排除測試專案與測試方法

當你開始 Live Unit Testing 時,會出現 Live Unit Test 工具視窗,並提示你選擇想由 Live Unit Test 測試的測試集合。

截圖顯示了首次啟動 Live 單元測試時工具視窗。

對於較小的解決方案,單元測試執行時間非常短,選擇 「包含所有測試」,讓即時單元測試執行所有測試。

對於擁有多個測試專案的大型解決方案,你可以透過編輯播放清單來控制哪些專案和專案中的個別方法參與 Live 單元測試。 例如,如果你的解決方案包含數百個測試專案,你可以選擇一組目標測試專案參與即時單元測試。

你可以透過編輯即時單元測試播放清單來選擇 Live 單元測試應該執行什麼,這個功能就像 測試檔案總管裡的播放清單一樣。

有多種方式可以編輯 Live Unit Test 播放清單:

  • 即時單元測試工具視窗
  • 程式碼編輯器視窗
  • 方案總管
  • 在測試程式碼中以程式化方式

Live 單元測試會將包含/排除狀態儲存為使用者設定,並在解決方案關閉與重新開啟時記住。

即時單元測試工具視窗

你可以使用即時單元測試標籤的播放清單編輯器,將專案、命名空間或類別納入或排除執行。 在工具視窗中選擇 編輯播放清單

你可以選擇或清除樹狀檢視元素,以包含或排除測試。 舉例來說,如果你檢查單一測試,當有變更時,Live Unit Testing 會執行該測試。 如果你選擇一個類別,該類別中的所有測試都會執行,並且新增到該類別的測試也會執行。

顯示 Live Unit Testing 播放清單編輯器的截圖。

程式碼編輯器視窗

你可以使用程式碼編輯器視窗來包含或排除個別測試方法。 在程式碼編輯器視窗中右鍵點擊測試方法的簽名或主體,並選擇以下選項之一:

  • 即時單元測試>包含 <選定方法>
  • 即時單元測試>排除 <選定方法>
  • 即時單元測試>排除所有但<選定的方法>

方案總管

要選擇單元測試中的個別專案,啟動即時單元測試後,請依照以下步驟操作:

  1. 解決方案總管 中右鍵點擊該解決方案,選擇 「即時單元測試>排除 」以排除整個解決方案。
  2. 右鍵點擊你想包含在測試中的每個測試專案,並選擇 「即時單元測試>包含」。

在測試程式碼中以程式化方式

你可以套用這個 ExcludeFromCodeCoverageAttribute 屬性,程式化地排除方法、類別或結構,避免在即時單元測試中回報其覆蓋範圍。

請使用以下屬性排除個別方法,以將它們從 Live Unit Testing 中排除:

  • x單元[Trait("Category", "SkipWhenLiveUnitTesting")]
  • NUnit[Category("SkipWhenLiveUnitTesting")]
  • MSTest[TestCategory("SkipWhenLiveUnitTesting")]

使用以下屬性來排除整個測試組合,從即時單元測試中剔除:

  • x單元[assembly: AssemblyTrait("Category", "SkipWhenLiveUnitTesting")]
  • NUnit[assembly: Category("SkipWhenLiveUnitTesting")]
  • MSTest[assembly: TestCategory("SkipWhenLiveUnitTesting")]

檢視覆蓋範圍視覺化

啟用即時單元測試後,它會在 Visual Studio 編輯器中更新每一行程式碼,告訴你你所寫的程式碼是否被單元測試覆蓋,以及涵蓋它的測試是否通過。

下圖顯示了包含通過與失敗測試的程式碼行,以及未被測試涵蓋的程式碼行數。 帶有綠色「✓」的項目僅通過測試。 帶有紅色「x」的線條會被一個或多個未通過的測試覆蓋。 帶有藍色「➖」的線條不會被任何考試涵蓋。

顯示 Visual Studio 程式碼覆蓋範圍的截圖。

當你修改程式碼編輯器中的程式碼時,即時單元測試覆蓋率視覺化會立即更新。 在處理編輯過程中,視覺化會改變,透過在通過、失敗及未覆蓋符號下方加入圓整計時器影像,以顯示資料非最新,如下圖所示。

截圖顯示 Visual Studio 中程式碼覆蓋率,並附有計時器圖示。

獲取測試狀態資訊

將游標懸停在程式碼視窗中代表通過或失敗的符號上,您可以查看有多少測試命中該行。 要查看各測試的狀態,請選擇符號。

顯示 Visual Studio 中某符號測試狀態的截圖。

除了提供測試名稱和結果外,工具提示還能讓你重跑或除錯測試集合。 如果你在工具提示中選擇一個或多個測試,也可以只執行或除錯這些測試。 這個動作讓你能在不離開程式碼視窗的情況下除錯測試。

除錯時,除了觀察你可能已設定的斷點外,當除錯器執行 Assert 的方法回傳意外結果時,程式執行會暫停。

當你將滑鼠移到提示中失敗的測試上時,它會展開以提供更多失敗的資訊,如下圖所示。 要直接進入失敗測試,請在工具提示中按兩下。

Visual Studio 中顯示測試失敗的工具提示資訊的截圖。

當你進入失敗測試時,Live 單元測試會在方法簽名中視覺化標示出具備以下條件的測試:

  • 通過 (以半滿的燒杯和綠色的「✓」表示)。
  • 失敗 (以半滿的燒杯和紅色「🞩」表示)。
  • 未參與即時單元測試(用半滿的燒杯和藍色「➖」表示)。

非測試方法不會用符號來識別。 下圖展示了所有四種方法類型。

截圖顯示 Visual Studio 中測試方法的通過或失敗符號。

診斷並修正測試失敗

從失敗的測試中,你可以輕鬆除錯產品程式碼、編輯,然後繼續開發你的應用程式。 因為即時單元測試是在背景執行,你不需要在除錯、編輯和繼續的循環中停止和重啟即時單元測試。

例如,前一張圖片中顯示的測試失敗,是因為測試方法錯誤地假設當非字母字元傳入System.Char.IsLower方法時,會返回true。 修正測試方法後,所有測試都應該通過。 你不必暫停或停止即時單元測試。

即時單元測試視窗

即時單元測試類似 於測試檔案總管,提供一個介面,讓你能執行、除錯測試並分析測試結果。 啟用即時單元測試時, 測試檔案總管 中單元測試的狀態會立即更新。 你不需要明確執行單元測試。

當未啟用或停止即時單元測試時, 即時單元測試 會顯示上次執行測試時的單元測試狀態。 重新啟動即時單元測試後,必須修改原始碼才能重新執行測試。

你可以在 Visual Studio 頂層選單中選擇「Test>Live Unit Test Start>」來啟動即時單元測試。 您也可以使用「視圖」>其他視窗>中的「即時單元測試視窗」來開啟即時單元測試視窗。

你可能會注意到在 即時單元測試 視窗中,有些測試會淡出。例如,當你停止並重新啟動 Live Unit Testing 時,Live Unit Test 視窗會淡出所有測試,如下圖所示。

模糊的測試結果顯示該測試並非最新的 Live Unit 測試的一部分。 只有在偵測到測試變更或其相依關係時,測試才會執行。 如果沒有變化,就能避免不必要的測試。 在這個案例中,灰色的測試結果仍然是「最新的」,雖然它並非最新一次測試的一部分。

顯示測試檔案總管中淡出測試的截圖。

你可以透過修改程式碼來重跑任何看起來已經消失的測試。

即時單元測試自動執行並更新測試結果,與明確從 測試檔案總管執行測試之間存在一些差異。 這些差異包括:

  • 測試總管 視窗執行或除錯測試時,會執行一般的二進位檔。 即時單元測試執行已帶儀器的二進位檔。
  • 即時單元測試不會建立新的應用程式域來執行測試。 取而代之的是,它會從預設網域執行測試。 從 測試檔案總管 視窗執行的測試確實會建立一個新的應用程式域。
  • 即時單元測試會在每個測試組件中依序執行測試。 在 測試檔案總管 視窗中,你可以選擇同時執行多個測試。

取消即時單元測試的執行

Live 單元測試會在你修改程式碼時持續執行測試。 如果執行進行中且你做了更多程式碼變更,Live 單元測試會在等待第一次執行完成時排隊再執行一次。

每次儲存檔案時,Live Unit Testing 會取消正在執行的第一個測試,並立即排程等待中的測試。 這個流程有助於處理第一次跑很久才完成的情況。

另請參閱