使用程式碼涵蓋範圍來決定所測試的程式碼數量

若要判斷單元測試等自動程式化測試正在測試的專案程式碼比例,您可使用 Visual Studio 程式碼涵蓋範圍功能。 為有效防範錯誤 (bug),您的測試應使用或「涵蓋」大部分程式碼。

程式碼涵蓋範圍分析適用於受控程式碼 (CLI) 和非受控程式碼 (機器碼)。 同時支援靜態和動態檢測。 若要在命令列案例中使用程式碼涵蓋範圍,請使用 vstest.console.exeMicrosoft.CodeCoverage.Console 工具,這是 dotnet-coverage 的延伸模組,也支援機器碼。

當您使用 [測試總管] 執行測試方法時,可在 [測試] 功能表之下取得程式碼涵蓋範圍選項。 結果資料表會顯示程式碼在每個組件、類別和程序中執行的百分比。 來源編輯器會醒目提示已測試的程式碼。 您可以使用 Cobertura 等熱門格式匯出結果。

需求

程式碼涵蓋範圍功能僅適用於 Visual Studio Enterprise 版本。

注意

針對 .NET 程式代碼涵蓋範圍,您也可以使用命令行工具 dotnet-coverage

分析程式碼涵蓋範圍

  1. 在 [測試] 功能表上,選取 [分析所有測試的程式碼涵蓋範圍]

    有已標示分析程式碼涵蓋範圍的測試功能表螢幕擷取畫面。

    有已標示分析程式碼涵蓋範圍的測試功能表螢幕擷取畫面。

    提示

    您也可以從 [測試總管] 工具視窗執行程式碼涵蓋範圍。

  2. 測試執行之後,若要查看哪些行已執行,請在 [程式碼涵蓋範圍結果] 視窗中選擇 [Visual Studio 中分析程式碼涵蓋範圍的螢幕擷取畫面顯示程式碼涵蓋範圍著色]。 根據預設,測試所涵蓋的程式碼會以淺藍色醒目提示。

    展示反白顯示的程式碼涵蓋範圍螢幕擷取畫面

    展示反白顯示的程式碼涵蓋範圍螢幕擷取畫面

    在 [顯示程式碼涵蓋範圍著色] 選項的下拉式清單中,您可以選擇將著色套用至程式碼行、左邊界中的字符或兩者。

  3. 若要變更色彩或使用粗體格式,請選擇 [工具]>[選項]>[環境]>[字型和色彩]>[顯示設定: 文字編輯器]。 在 [顯示項目] 之下,調整 [涵蓋範圍] 項目的設定,例如 [涵蓋範圍未觸及的區域]

    展示程式碼涵蓋範圍字體與顏色的螢幕擷取畫面

    展示程式碼涵蓋範圍字體與顏色的螢幕擷取畫面。

  4. 如果結果顯示涵蓋範圍較小,請檢查不會執行的部分程式碼,並撰寫更多測試來涵蓋這些項目。 開發小組通常以 80% 的程式碼涵蓋範圍為目標。 某些情況可以接受較小的涵蓋範圍。 例如,從標準範本產生之程式碼涵蓋範圍較小是可接受的。

提示

若要最佳化程式碼涵蓋範圍:

  • 關閉編譯器最佳化。
  • 如果使用非受控程式碼 (機器碼),請使用偵錯組建。
  • 為每個組件產生 .pdb (符號) 檔案。

如果沒有得到預期的結果,請參閱針對程式碼涵蓋範圍進行疑難排解

更新程式碼後不要忘記再次執行程式碼涵蓋範圍。 修改程式碼後或執行測試時,並不會自動更新涵蓋範圍結果和程式碼著色。

提示

從 Visual Studio 2022 Update 2 開始,選取 [工具]> [選項] > [環境] > [預覽功能],然後選取 [程式碼涵蓋範圍體驗改善],然後重新啟動 Visual Studio,即可啟用更快的程式碼涵蓋範圍測試結果。

區塊或行報告

程式碼涵蓋範圍以「區塊」(Block) 計算。 區塊是只有一個進入點及一個結束點的程式碼部分。 如果程式的控制流程在測試回合期間通過區塊,該區塊即屬於覆蓋的區塊。 區塊使用次數不會影響結果。

您也可以選擇表格標題中的 [新增/移除資料行],顯示各行的結果。 某些使用者習慣以行計算,因為百分比較符合您在原始程式碼中看見的片段大小。 長區塊的計算也視同單一區塊,即便長區塊佔用許多行。

提示

程式碼行可以包含一個以上的程式碼區塊。 如果是這種情況,且測試回合執行程式碼行中的所有程式碼區塊,則會以一行計算。 如果執行了程式碼行中的部分 (而非全部) 程式碼區塊,則會計算為部分行。

篩選程式碼涵蓋範圍結果

[程式碼涵蓋範圍結果] 視窗通常會顯示整個解決方案的結果。 您可以篩選結果,只顯示目前分支中已更新檔案的結果。

  • 若要檢視變更集報告,請在 [程式碼涵蓋範圍結果] 視窗中選取 [設定程式碼涵蓋範圍檢視] 圖示。 然後,從 [報告內容] 下拉式清單中選取 [變更集報告]。 更新 [作用中存放庫] 和 [基底分支] 來進行比較,以提供比較報告。

從 [程式碼涵蓋範圍結果] 視窗中的搜尋方塊,有數種方式可以篩選報告。

  • 若要 [依名稱搜尋] (只顯示視窗中符合搜尋字串的內容),請在搜尋方塊中輸入搜尋字串。
  • 若要 [依類型篩選],請在搜尋方塊中輸入類型的名稱。
  • 若要 [全部顯示],則清除搜尋方塊。
  • 若要 [顯示 100% 完整涵蓋範圍],請在搜尋方塊中輸入 "Covered (%Lines)":"100"。
  • 若要顯示 (>0% && < 100%) 部分涵蓋,請輸入 "部分涵蓋 (%Lines)":"<##”,將 ## 取代為涵蓋的百分比。
  • 若要 [顯示 0% 涵蓋範圍],請在搜尋方塊中輸入 "Not Covered (%Lines)":"0"。

管理程式碼涵蓋範圍結果

[程式碼涵蓋範圍結果] 視窗通常會顯示最近執行的結果。 如果您變更測試資料,或者每次只執行部分測試,結果就會有所不同。

[程式碼涵蓋範圍結果] 視窗也可用來檢視之前的結果,或是在其他電腦上得到的結果。

您可以合併數個回合的結果,例如合併使用不同測試資料的回合。

  • 若要檢視先前的結果集,請從下拉式功能表中選取它。 當您開啟新的方案時,功能表會顯示暫存清單。

  • 若要檢視上一個工作階段的結果,請選擇 [匯入程式碼涵蓋範圍結果],巡覽至方案中的 TestResults 資料夾,然後匯入 .coverage 檔案。

    如果在產生 .coverage 檔案之後變更過原始程式碼,涵蓋範圍著色可能會不正確。

  • 若要以文字顯示結果,請選擇 [匯出程式碼涵蓋範圍結果]。 這樣會產生一個易讀的 .coveragexml 檔案,您可以使用其他工具處理這個檔案,也可以透過郵件輕鬆傳送該檔案。 您也可以選取匯出格式,例如 Cobertura。

  • 若要將結果傳送給他人,請傳送 .coverage 檔案或匯出的 .coveragexml 檔案。 然後,他們就可以匯入您所傳送的檔案。 如果他們有相同版本的原始程式碼,就可以看見涵蓋範圍著色。

合併不同回合的結果

在某些情況下,會根據測試資料使用程式碼中的不同區塊。 因此,建議您合併不同測試回合的結果。

例如,假設您在執行輸入 "2" 的測試時發現特定函式的涵蓋範圍是 50%。 當您第二次輸入 "-2" 執行測試時,您會在涵蓋範圍著色檢視中看見函式涵蓋範圍多了另外的 50%。 您現在合併了兩個測試回合的結果,而報告和涵蓋範圍著色檢視顯示涵蓋範圍是該函式的 100%。

使用 [程式碼涵蓋範圍視窗中合併按鈕的圖示。合併程式碼涵蓋範圍結果] 即可執行。 您可以選擇最近的回合或匯入之結果的任何組合。 如果您要合併匯出的結果,必須先匯入結果。

使用 [匯出程式碼涵蓋範圍結果],儲存合併作業的結果。

合併的限制

  • 如果您從不同版本的程式碼合併涵蓋範圍資料,結果會個別顯示而不會合併。 若要取得完整的合併結果,請使用相同組建的程式碼,只變更測試資料。

  • 如果合併先匯出再匯入的結果,您只能依行而不是依區塊檢視結果。 使用 [新增/移除資料行] 命令顯示行資料。

  • 如果您合併 ASP.NET 專案測試的結果,會顯示個別測試的結果而非合併的結果。 此行為只適用於 ASP.NET 成品本身:會合併其他任何組件的結果。

在程式碼涵蓋範圍結果中排除項目

如果程式碼是從文字範本產生的,您可能會想要將程式碼中的特定項目從排除涵蓋範圍分數中排除。 將 System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverageAttribute 屬性新增至下列任一程式碼項目:類別、結構、方法、屬性、屬性 setter 或 getter、事件。

提示

排除類別並不會排除其衍生類別。

例如:

using System.Diagnostics.CodeAnalysis;
...
public class ExampleClass1
{
    [ExcludeFromCodeCoverage]
    void ExampleMethod() {...}

    [ExcludeFromCodeCoverage] // exclude property
    int ExampleProperty1
    { get {...} set{...}}

    int ExampleProperty2
    {
        get
        {
            ...
        }
        [ExcludeFromCodeCoverage] // exclude setter
        set
        {
            ...
        }
    }

}
[ExcludeFromCodeCoverage]
class ExampleClass2 { ... }

使用下列巨集:

ExcludeFromCodeCoverage(ExclusionName, L"FunctionName");

ExcludeSourceFromCodeCoverage(ExclusionName, L"SourceFilePath");

  • ExclusionName 是任何唯一名稱。

  • FunctionName 是完整函式名稱。 可以包含萬用字元。 例如,若要排除某個類別的所有函式,可以寫成 MyNamespace::MyClass::*

  • SourceFilePath.cpp 檔案的本機或 UNC 路徑。 可以包含萬用字元。 下列範例會排除特定目錄中的所有檔案: \\MyComputer\Source\UnitTests\*.cpp

  • #include <CodeCoverage\CodeCoverage.h>

  • 請呼叫全域命名空間中的排除巨集,而不要呼叫任何命名空間或類別中的排除巨集。

  • 您可以在單元測試程式碼檔案或應用程式程式碼檔案中排除。

  • 您必須設定編譯器選項或使用 #pragma managed(off) 將排除編譯為 Unmanaged (機器碼)。

注意

若要排除 C++/CLI 程式碼中的函式,請將 [System::Diagnostics::CodeAnalysis::ExcludeFromCodeCoverage] 屬性套用至該函式。 這和 C# 的做法相同。

包含或排除其他項目

程式碼涵蓋範圍分析只能對載入的組件或與 .dll.exe 檔案位於同一個目錄中的 .pdb 檔案執行。 因此,在某些情況下,您可以藉由取得包含適當 .pdb 檔案的複本來擴充所包含的組件集。

您可以撰寫 .runsettings 檔案進一步控制執行程式碼涵蓋範圍分析時選取的組件和項目。 例如,您可以排除特定種類的組件,而不需要在其類別中加入屬性。 如需詳細資訊,請參閱自訂程式碼涵蓋範圍分析

在 Azure Pipelines 中分析程式碼涵蓋範圍

當您檢查程式碼時,您的測試會在組建伺服器上與其他小組成員的測試一起執行。 在 Azure Pipelines 中分析程式碼覆蓋範圍,可針對整個專案的覆蓋範圍取得最新、最完整的分析結果,因此它是非常有用的方法。 Azure Pipelines 中的程式碼涵蓋範圍也包含自動化系統測試,和通常不會在開發電腦上執行的其他自動程式化測試。

從命令列分析程式碼涵蓋範圍

若要從命令列執行測試,請使用 vstest.console.exe 公用程式。 程式碼涵蓋範圍是 /EnableCodeCoverage 選項所叫用之 vstest.console.exe 公用程式的選項。

  1. 啟動 Visual Studio 的開發人員命令提示字元:

    在 Windows [開始] 功能表中,搜尋 Developer Command Prompt for VS 並選取與搜尋文字相關聯的應用程式結果。

  2. 在命令提示字元中,執行下列命令:

    vstest.console.exe MyTestAssembly.dll /EnableCodeCoverage
    

    提示

    針對開發人員 PowerShell,殼層的起始目錄是 Visual Studio 專案位置。 以路徑和測試檔案名稱取代 MyTestAssembly.dll。 如需詳細資訊,請參閱 VSTest.Console.exe 命令列選項

疑難排解

如果您看不到程式碼涵蓋範圍結果,針對程式碼涵蓋範圍進行疑難排解一文可能對您有所幫助。