使用程式碼涵蓋範圍來決定所測試的程式碼數量
若要判斷由自動程式碼 UI 測試實際測試 (例如單元測試)您的專案程式碼的比例,您可以使用 Visual Studio 程式碼涵蓋範圍功能。若要有效防範 Bug,您的測試應該要納入或覆蓋您的每個程式碼的大比例。
程式碼涵蓋範圍分析可以套用到 Managed (CLI) 和 Unmanaged (原生) 程式碼。
當您使用測試總管時執行測試方法程式碼涵蓋範圍是個選項。結果清單會顯示在每個組件、類別和方法執行程式碼的百分比。此外,原始檔編輯器會顯示要測試的程式碼。
需求
- Visual Studio Ultimate, Visual Studio Premium
在測試總管分析單元測試的程式碼涵蓋範圍
在 [測試] 功能表上,選擇 [分析程式碼涵蓋範圍]。
若要查看哪些行上執行,請選取 [顯示程式碼涵蓋範圍著色]。
若要修改色彩,或使用粗體格式,選取 [工具], [選項], [環境], [字型和色彩], [Show settings for:文字編輯器]。在 [顯示項目] 之下,請調整涵蓋範圍項目。
如果結果顯示低涵蓋範圍,請檢閱程式碼部分不會執行,並撰寫更多測試報告這些項目。開發小組通常大約以 80% 程式碼涵蓋範圍為目標。在某些情況下,較低的涵蓋範圍是可接受的。例如,一些從標準範本產生程式碼有較低的涵蓋範圍是可接受的。
提示 |
---|
取得正確結果:
如果沒有得到預期的結果,請參閱 疑難排解程式碼涵蓋範圍。 |
報告在區塊或行
程式碼涵蓋範圍在區塊計數。區塊是剛好一個進入點及結束點的程式碼區段。在測試回合期間,如果程式控制流程通過區塊,此區塊會計算為覆蓋過的區塊。區塊中不會影響結果的效果的次數。
您也可以藉由可以選取表格標題的 [新增/移除資料行] 將結果顯示為資料行。如果測試回合中在所有程式碼區塊執行的任何程式碼,它會計算為一行。其中一行包含執行的一些程式碼,該計算為一部分涵蓋行的區塊和陣列。
某些使用者慣用算一行,因為百分比最能符合您在原始程式碼片段的大小。計算長區塊也會計算為一個區塊,即使佔用太多行。
處理常式中的程式碼涵蓋範圍結果
[程式碼涵蓋範圍結果] 視窗通常會顯示最近執行的結果。結果會有所不同,如果變更您的測試資料,或者,如果您每次只執行部分測試。
[程式碼涵蓋範圍] 視窗可用來檢視上一個在其他電腦上所得到的結果或結果。
您可以結合數個回合的結果,例如從使用其他測試資料的執行。
**檢視先前的結果集。**選取,然後從下拉式功能表。當您開啟新的方案時,會顯示在一個暫存清單。
檢視自上次會議的結果,選取 [匯入程式碼涵蓋範圍結果],巡覽至您的方案的 TestResults 資料夾,並匯入 .coverage 檔案。
涵蓋範圍著色可能是不正確的,如果自動從 .coverage 檔案所產生的原始程式碼已變更。
可以讓結果讀取做為文字,選取 [out 程式碼涵蓋範圍結果]。這會產生您可以處理與其他工具或輕鬆地傳送郵件的可讀取的 .coveragexml 檔案。
將結果傳送其他人,傳送 .coverage 檔案或匯出的 .coveragexml 檔案。它們可以匯入檔案。如果具有原始程式碼的相同版本,其可以看到涵蓋範圍的色彩。
從不同的執行結果去合併。
在一些情況下,是以測試資料中使用不同的區塊中的程式碼。因此,您可能會想要合併不同測試回合的結果。
例如,假設,在執行與輸入「2 」中的測試時,您會發現特定函式中的 50%被涵蓋 。當您第二次輸入「- 2 」執行測試時,您會在涵蓋範圍色彩看到函式中的50%被涵蓋。現在您合併兩個測試回合的結果和報表和涵蓋範圍色彩檢視示範 100% 函式已涵蓋的。
使用 [合併程式碼涵蓋範圍結果] 這麼做。您可以選取最近執行或匯入結果的任何組合。如果您要合併匯出的結果,必須先匯入這些檔案。
使用 [out 程式碼涵蓋範圍結果] 儲存合併作業的結果。
在合併的限制
如果您會從不同版本的程式碼合併涵蓋範圍資料,結果會個別顯示,但是不會合併。若要取得完整合併的結果,使用程式碼的相同組建,只變更測試資料。
如果匯出然後匯入您的合併結果,您只能依行檢視結果,而不是由區塊。使用 [新增/移除資料行] 命令顯示資料行。
如果您合併 ASP.NET 測試的結果,個別測試的結果會顯示,但不會合併。這只適用於 ASP.NET 成品:其他組件的結果將會進行合併。
除了以程式碼涵蓋範圍結果的項目
您可能想要從涵蓋範圍分數排除特定項目在您的程式碼,例如,程式碼是從文字範本產生。將屬性 System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage 加至下列任何程式碼項目:類別、結構、方法、屬性、屬性 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 { ... }
Imports System.Diagnostics.CodeAnalysis
Class ExampleClass1
<ExcludeFromCodeCoverage()>
Public Sub ExampleSub1()
...
End Sub
' Exclude property
< ExcludeFromCodeCoverage()>
Property ExampleProperty1 As Integer
...
End Property
' Exclude setter
Property ExampleProperty2 As Integer
Get
...
End Get
<ExcludeFromCodeCoverage()>
Set(ByVal value As Integer)
...
End Set
End Property
End Class
<ExcludeFromCodeCoverage()>
Class ExampleClass2
...
End Class
// A .cpp file compiled as managed (CLI) code.
using namespace System::Diagnostics::CodeAnalysis;
...
public ref class ExampleClass1
{
public:
[ExcludeFromCodeCoverage]
void ExampleFunction1() { ... }
[ExcludeFromCodeCoverage]
property int ExampleProperty2 {...}
property int ExampleProperty2 {
int get() { ... }
[ExcludeFromCodeCoverage]
void set(int value) { ... }
}
}
[ExcludeFromCodeCoverage]
public ref class ExampleClass2
{ ... }
除了項目是原生 C++ 程式碼
排除在 C++ 程式碼中的未處理 (原生) 項目:
#include <CodeCoverage\CodeCoverage.h>
...
// Exclusions must be compiled as unmanaged (native):
#pragma managed(push, off)
// Exclude a particular function:
ExcludeFromCodeCoverage(Exclusion1, L"MyNamespace::MyClass::MyFunction");
// Exclude all the functions in a particular class:
ExcludeFromCodeCoverage(Exclusion2, L"MyNamespace::MyClass2::*");
// Exclude all the functions generated from a particular template:
ExcludeFromCodeCoverage(Exclusion3, L"*::MyFunction<*>");
// Exclude all the code from a particular .cpp file:
ExcludeSourceFromCodeCoverage(Exclusion4, L"*\\unittest1.cpp");
// After setting exclusions, restore the previous managed/unmanaged state:
#pragma managed(pop)
使用下列巨集:
-
ExcludeFromCodeCoverage(ExclusionName, L"函式名稱");
ExcludeSourceFromCodeCoverage(ExclusionName, L"原始檔案路徑");
排除名稱 都是唯一的名稱。
函式名稱 就是完整的函式名稱。它可以包含萬用字元。例如,排除類別的所有函式,寫入 MyNamespace::MyClass::*
原始檔案路徑 是 .cpp 檔案的本機或通用命名慣例 (Universal Naming Convention,UNC) 路徑。它可以包含萬用字元。下列範例會排除特定目錄中的所有檔案 \\MyComputer\Source\UnitTests\*.cpp 。
#include <CodeCoverage\CodeCoverage.h>
將呼叫排除在全域命名空間的巨集,不在任何命名空間或類別中。
您可以在單元測試程式碼檔或應用程式的程式碼檔放置排除。
必須排除編譯為 Unmanaged (原生) 使用 #pragma managed(off),程式碼,將編譯器選項或。
注意事項 |
---|
若要排除 C++/CLI 的函式程式碼,請將屬性套用至 [System::Diagnostics::CodeAnalysis::ExcludeFromCodeCoverage] 函式。這是與之相同的 C#。 |
包含或排除其他項目
程式碼涵蓋範圍分析只在所要載入的組件上執行,並且 .pdb 檔案會在與此 .dll 或 .exe 檔相同目錄。因此在其他情況下,您可以藉由取得包含適當的 .pdb 檔組件集的複本去擴充設定。
您可以運用組件和項目的程式碼涵蓋範圍分析已選取藉由撰寫 .runsettings 檔案更多的控制。例如,您可以排除特定種類的組件,而不需要將屬性加入至類別中。如需詳細資訊,請參閱自訂程式碼涵蓋範圍分析。
在組建服務中分析程式碼涵蓋範圍
當您檢查程式碼時,您的測試在組建伺服器上與任何其他測試時與其他小組成員執行。(如果您尚未設定此功能,請參閱 在建置流程中執行測試)。因為這會涵蓋範圍最新和全面性的圖片整個專案的程式碼剖析,在組建服務的程式碼涵蓋範圍很有用。它也將包含您在開發電腦上通常不執行自動化系統測試和其他測試的測試。
在團隊總管中,開啟組建,並且增加或編輯組建定義
在 [流程] 頁面上,展開 [自動化測試], [測試來源], [回合設定]。設定 [回合組態檔案中的型別] 至 [程式碼涵蓋範圍啟用]。
如果您有一個以上的測試來源定義,請重複每一個這個步驟。
但沒有名為 [回合組態檔案中的型別]的欄位。
在 [自動化測試] 下,選取在行尾的 [測試組件。] 和選擇省略符號按鈕 [...] 。在 [加入/編輯測試回合] 對話方塊,請在 [測試執行器] 底下,選取 [Visual Studio 測試執行器]。
在組建執行後,程式碼涵蓋範圍結果會附加至測試回合而且出現在組建摘要。
在命令列程式碼剖析程式碼涵蓋範圍
若要從命令列執行測試,請使用 vstest.console.exe。程式碼涵蓋範圍是此公用程式的選項。如需詳細資訊,請參閱VSTest.Console.exe 命令列選項。
啟動 Visual Studio Developer 命令提示字元中輸入:
在視窗中 [開始] 功能表上,選擇 [所有程式], [Microsoft Visual Studio], [Visual Studio 工具], [開發人員命令提示字元]。
執行:
vstest.console.exe MyTestAssembly.dll /EnableCodeCoverage
疑難排解
如果您沒有看到程式碼涵蓋範圍結果,請參閱 疑難排解程式碼涵蓋範圍。
外部資源
指引
測試以搭配使用 Visual Studio 2012RC–第 2 章:單元測試:內部測試