天天看點

使用 Visual Studio 和 TFS 進行 Agile C++ 開發和測試

緻力于在 Visual C++ 中建構的應用程式的開發人員和測試人員。 作為一名開發人員,如果能夠提高工作效率,編寫較高品質的代碼,并能夠根據需要重寫代碼以改善體系結構,而不必擔心妨礙任何内容,豈不是很好? 作為一名測試人員,是否希望花更少的時間來編寫和維護測試,以便有時間進行其他測試活動?

使用 Visual Studio 2010 和 Team Foundation Server (TFS) 2010。使用 TFS 2010 來進行版本控制、工作跟蹤、持續內建、代碼覆寫率收集和報告。

作為開發人員,以下是目标:

  • 無建構破壞
  • 無回歸
  • 自信地進行重構
  • 自信地修改體系結構
  • 通過測試驅動開發 (TDD) 來推動設計

當然,品質是這些目标背後的重要“原因”。實作這些目标後,開發人員的生活将比其不是開發人員時更加高效和有趣。

對于我們的測試人員,我将僅關注 Agile 測試人員的一個方面:編寫自動化測試。測試人員編寫自動化測試時,他們的目标包括無回歸、接受驅動開發以及收集和報告代碼覆寫率。

當然,我們的測試人員所做的不僅僅是編寫自動化測試。我們的測試人員負責收集代碼覆寫率,因為我們希望代碼覆寫率數字包含所有測試結果,而不僅僅是單元測試結果(稍後會對此進行詳細介紹)。

在本文中,我将介紹我們團隊用以實作此處所述目标的不同工具和技術。

使用網關簽入來消除建構破壞

過去,我們的團隊使用分支來確定測試人員始終擁有用于測試的穩定版本。但是,維護分支會産生開銷。我們擁有網關簽入後,僅使用分支進行釋出,這是一個很好的轉變。

使用網關簽入需要您設定建構控件以及一個或多個建構代理。我不打算在此對該主題進行介紹,但是您可以在 bit.ly/jzA8Ff 中 MSDN 庫頁面上的“管理 Team Foundation Build”中找到詳細資訊。

設定并運作建構代理後,您可以通過在 Visual Studio 中執行以下步驟來建立網關簽入的新建構定義:

  1. 在菜單欄中單擊“視圖”,然後單擊“團隊資料總管”,以確定團隊資料總管工具視窗可見。
  2. 展開您的團隊項目,然後右鍵單擊“建構”。
  3. 單擊“建立建構定義”。
  4. 單擊左側的“觸發器”,然後選擇“網關簽入”,如圖 1 所示。
    使用 Visual Studio 和 TFS 進行 Agile C++ 開發和測試
    圖 1 為您的建立建構定義選擇網關簽入選項
  5. 單擊“建構預設值”,然後選擇建構控制器。
  6. 單擊“處理”,然後選擇要建構的項目。

儲存該建構定義後(我們稱為“網關簽入”),您将會在送出您的簽入後看到一個新對話框(請參見圖 2)。單擊“建構更改”來建立擱置集并将其送出至建構伺服器。如果沒有建構錯誤,并且通過所有單元測試,則 TFS 将為您簽入更改。否則,它會拒絕簽入。

使用 Visual Studio 和 TFS 進行 Agile C++ 開發和測試

圖 2 網關簽入對話框

網關簽入十分有用,因為其可確定您永遠不會破壞建構。它們也能確定通過所有單元測試。開發人員在簽入前,往往很容易忘記運作所有測試。但是使用網關簽入後,這類情況将不再出現。

編寫 C++ 單元測試

現在,您已了解如何運作作為網關簽入一部分的單元測試,那麼我們來看看您為本機 C++ 代碼編寫這些單元測試的一種方法。

我非常喜歡 TDD,原因如下:它能幫我關注行為,使我的設計更簡單。我也有一個測試形式的安全網,這些測試定義了行為約定。我可以重構,而不必擔心因不小心違反行為約定而引入錯誤。我也了解其他開發人員不會中斷他們所不知道的所需行為。

團隊中的一名開發人員有方法使用内置測試運作程式 (mstest) 來測試 C++ 代碼。他使用調用本機 C++ DLL 公開的公共函數的 C++/CLI 來編寫 Microsoft .NET Framework 單元測試。我在本部分對該方法進行了進一步的介紹,使您能夠直接執行個體化生産代碼内部的本機 C++ 類。換句話說,除公共接口外,您還可以對其他内容進行測試。

解決方案是将生産代碼添加到靜态庫中,該靜态庫能連結至單元測試 DLL、生産 EXE 或 DLL 中,如圖 3 所示。

使用 Visual Studio 和 TFS 進行 Agile C++ 開發和測試

圖 3 測試和生産通過靜态庫共享相同代碼

設定項目遵循該過程所需的步驟如下所示:首先建立靜态庫:

  1. 在 Visual Studio 中,依次單擊“檔案”、“建立”和“項目”。
  2. 在“已安裝的模闆”清單中單擊“Visual C++”(您将需要展開“其他語言”)。
  3. 單擊項目類型清單中的“Win32 項目”。
  4. 輸入項目的名稱,然後單擊“确定”。
  5. 單擊“下一步”,單擊“靜态”庫,然後單擊“完成”。

現在建立測試 DLL。設定測試項目還需要執行若幹其他步驟。需要建立項目,并使其能夠通路靜态庫中的代碼和頭檔案。

首先,在“解決方案資料總管”視窗中右鍵單擊解決方案。單擊“添加”,然後單擊“新項目”。單擊模闆清單中 Visual C++ 節點下的“測試”。鍵入項目名稱(我們的團隊在項目名稱末尾添加了“UnitTests”),然後單擊“确定”。

在解決方案資料總管中,右鍵單擊新項目,然後單擊“屬性”。單擊左側樹中的“常見屬性”。單擊“添加新引用”。單擊“項目”頁籤,選擇使用靜态庫的項目,并單擊“确定”來取消“添加引用”對話框。

展開左側樹中的“配置屬性”節點,然後展開 C/C++ 節點。單擊 C/C++ 節點下的“正常”。單擊“配置”組合框,然後選擇“所有配置”,以確定同時更改“調試”版本和“釋出”版本。

單擊“附加 Include 庫”,然後輸入靜态庫的路徑,在這裡您需要将靜态庫名稱替換為 MyStaticLib:

$(SolutionDir)\MyStaticLib;%(AdditionalIncludeDirectories)

單擊相同屬性清單中的“公共語言運作時支援”屬性,并将其更改為“公共語言運作時支援(/clr)”。

單擊“配置屬性”下的“正常”部分,并将“TargetName”屬性更改為“$(ProjectName)”。預設情況下,所有測試項目的該屬性被設定為“DefaultTest”,但是它應為您項目的名稱。單擊“OK”(确定)。

您将需要重複此過程的第一部分,以将靜态庫添加到生産 EXE 或 DLL 中。

編寫您的第一個單元測試

您現在應該擁有了編寫新單元測試所需的所有資訊。您的測試方法将為采用 C++ 編寫的 .NET 方法,是以文法将與本機 C++ 稍有不同。如果您了解 C#,将會發現它在許多方面是 C++ 和 C# 文法的一個混合。有關詳細資訊,請參閱 bit.ly/iOKbR0 上的 MSDN 庫文檔“針對 CLR 的語言功能”。

假設您要測試的類定義如下所示:

  1. #pragma once
  2. class MyClass {
  3. public:
  4. MyClass(void);
  5. ~MyClass(void);
  6. int SomeValue(int input);
  7. };

現在您需要為 SomeValue 方法編寫測試以指定該方法的行為。圖 4 顯示了簡單單元測試可能的外觀,其中顯示了整個 .cpp 檔案。

圖 4 簡單單元測試

  1. #include"stdafx.h"
  2. #include"MyClass.h"
  3. #include <memory>
  4. usingnamespace System;
  5. usingnamespace Microsoft::VisualStudio::TestTools::UnitTesting;
  6. namespace MyCodeTests {
  7. [TestClass]
  8. public ref class MyClassFixture {
  9. [TestMethod]
  10. void ShouldReturnOne_WhenSomeValue_GivenZero() {
  11. // Arrange
  12. std::unique_ptr<MyClass> pSomething(new MyClass);
  13. // Act
  14. int actual = pSomething->SomeValue(0);
  15. // Assert
  16. Assert::AreEqual<int>(1, actual);
  17. }

如果您對編寫單元測試不熟悉,我将使用稱為“Arrange,Act,Assert”的模式。“Arrange”部分設定所要測試方案的前置條件。“Act”部分為調用您要測試的方法的地方。“Assert”部分為您檢查方法是否按所需方式執行的地方。我想在每部分前添加一個注釋,以增加可讀性并簡化“Act”部分的查找。

測試方法都以“TestMethod”屬性标記,如圖 4 所示。這些方法又必須包含在以“TestClass”屬性标記的類中。

請注意,測試方法中的第一行建立了本機 C++ 類的新執行個體。我想使用 unique_ptr 标準 C++ 庫類來確定該執行個體會在測試方法結束後自動删除。是以您可以清楚地看到,您能夠将本機 C++ 與您的 CLI/C++ .NET 代碼混合。當然也會存在某些限制,我将在下一部分中對此進行概述。

同樣,如果您以前沒有編寫過 .NET 測試,可以使用 Assert 類提供的很多有用方法來檢查不同的條件。我想使用通用版本來明确我希望從結果獲得的資料類型。

請充分利用 C++/CLI 測試

如前所述,當您将本機 C++ 代碼和 C++/CLI 代碼混合時,需要注意一些限制。這些不同是由于兩個代碼庫間記憶體管理的不同而導緻的。本機 C++ 使用 C++ 的新運算符來配置設定記憶體,您需要自己釋放記憶體。配置設定一部分記憶體後,您的資料将始終位于同一位置。

另一方面,C++/CLI 代碼中的指針會因為該代碼從 NET Framework 繼承的垃圾收集模型而具有完全不同的行為。您可以使用 gcnew 運算符而不是新運算符來在 C++/CLI 中建立新 .NET 對象,這将為對象傳回對象句柄,而不是指針。句柄基本上是指向指針的多個指針。當垃圾收集在記憶體中移動托管對象時,它會根據新位置對句柄進行更新。

混合托管指針和本機指針時必須非常小心。我将介紹其中一些差異,并講述有關針對本機 C++ 對象充分利用 C++/CLI 測試的提示和技巧。

假設您要測試一個方法,其可傳回指向字元串的指針。在 C++ 中,您能夠以 LPCTSTR 來表示字元串指針。但是在 C++/CLI 中,通常以“String^”來表示 .NET 字元串。類名稱後的托字号表示托管對象的句柄。

以下是一個示例,說明如何測試方法調用傳回的字元串的值:

  1. LPCTSTR actual = pSomething->GetString(1);
  2. Assert::AreEqual<String^>("Test", gcnew String(actual));

最後一行包含所有詳細資訊。有一個 AreEqual 方法可接受受管字元串,但是沒有針對本機 C++ 字元串的相應方法。是以,您需要使用受管字元串。AreEqual 方法的第一個參數是一個受管字元串,是以盡管沒有使用 _T 或 L 将其标注為 Unicode 字元串,它實際上也是一個 Unicode 字元串。

String 類有一個接受 C++ 字元串的構造函數,是以您可以建立一個新的受管字元串,其将包含來自待測試方法的實際值,這樣 AreEqual 就可確定它們的值相同。

Assert 類有兩個極具吸引力的方法:IsNull 和 IsNotNull。然而,這些方法的參數是句柄而不是對象指針,這意味着您隻能将這些方法用于受管對象。相反,您可以使用 IsTrue 方法,如下所示:

  1. Assert::IsTrue(pSomething != nullptr, "Should not be null");

它能完成同樣的工作,但是需要使用更多的代碼。我添加了一個注釋,進而使期望在出現在測試結果視窗的消息中清晰明了,如圖 5 所示。

使用 Visual Studio 和 TFS 進行 Agile C++ 開發和測試

圖 5 在錯誤消息中顯示附加注釋的測試結果

共享設定和拆解代碼

應将測試代碼視為生産代碼。換句話說,應重構測試和生産代碼,以簡化測試代碼的維護。在某些情況下,測試類中的所有測試方法可能擁有一些共同的設定和拆解代碼。您可以指定在每項測試前運作的方法,也可以指定在每項測試後運作的方法(您可以使用其中一種,兩種或都不使用)。

TestInitialize 屬性标記了一種将在測試類中每個測試方法前運作的方法。同樣,TestCleanup 屬性标記了一種将在測試類中每個測試方法後運作的方法。例如:

  1. [TestInitialize]
  2. void Initialize() {
  3. m_pInstance = new MyClass;
  4. [TestCleanup]
  5. void Cleanup() {
  6. delete m_pInstance;
  7. MyClass *m_pInstance;

首先,請注意我針對 m_pInstance 使用了一個指向類的簡單指針。為什麼我沒有使用 unique_ptr 來管理生存期?

同樣,答案與混合本機 C++ 和 C++/CLI 有關。C++/CLI 中的執行個體變量是托管對象的一部分,是以它們隻能是托管對象的句柄以及指向本機對象或值類型的指針。您需要回到建立和删除基礎來管理本機 C++ 執行個體的生存期。

使用指向執行個體變量的指針

如果您正在使用 COM,則可能會遇到這種情況,即您希望編寫如下代碼:

  1. Void Test() {
  2. ...
  3. HRESULT hr = pSomething->GetWidget(&m_pUnk);
  4. IUnknown *m_pUnk;

這将無法編譯,并會産生如下錯誤消息:

無法将參數 1 從“cli::interior_ptr<Type>”轉換為“IUnknown **”

在本示例中,C++/CLI 執行個體變量位址類型為 interior_ptr<IUnknown *>,該類型與本機 C++ 代碼不相容。您想知道為什麼嗎?我僅需要一個指針。

測試類為托管類,是以該類的執行個體可以通過垃圾收集器在記憶體中移動。是以,如果您有指向執行個體變量的指針,則對象移動後,該指針将無效。

可以在本機調用過程中鎖定對象,如下所示:

cli::pin_ptr<IUnknown *> ppUnk = &m_pUnk;
HRESULT hr = pSomething->GetWidget(ppUnk);
                   

第一行鎖定執行個體,直至變量超出範圍,這将使您可以将指向執行個體變量的指針傳遞給本機 C++,盡管變量包含在托管測試類中。

編寫可測試的代碼

在本文的開頭,我提到了編寫可測試代碼的重要性。我使用 TDD 來確定代碼具有可測試性,但是某些開發人員更喜歡在編寫代碼後編寫測試。無論怎麼做,我們都不僅要考慮單元測試,同時還要考慮整個測試堆棧,這點非常重要。

Mike Cohn 是 Agile 著名的多産作者,他繪制了測試自動化金字塔,該金字塔提供了有關測試類型的内容以及每層上應進行的測試數。開發人員應該編寫所有或大多數單元群組件測試,并可能編寫一些內建測試。有關該測試金字塔的詳細資訊,請參閱 Cohn 的部落格文章“測試自動化金字塔的遺忘層”(bit.ly/eRZU2p)。

測試人員通常負責編寫驗收測試和 UI 測試。這些測試有時也稱為端到端測試或 E2E 測試。在 Cohn 的金字塔中,與其他類型測試的區域相比,UI 三角形是最小的。這意味着您需要編寫盡可能少的自動化 UI 測試。自動化 UI 測試往往非常脆弱,且編寫和維護成本較高。對 UI 所做的細小更改極易破壞 UI 測試。

如果您的代碼沒有編寫為可測試代碼,則您将可以輕松得到倒金字塔,其中大部分自動化測試為 UI 測試。這是一種很不好的情況,但底線是開發人員需確定測試人員可以在 UI 下編寫內建和驗收測試。

此外,無論出于什麼原因,我遇到的大部分測試人員都非常熟悉以 C# 編寫測試,而回避以 C++ 編寫測試。是以,我們的團隊需要在測試和自動化測試下的 C++ 代碼之間架起一個橋梁。橋梁采用裝置形式,這些裝置為 C++/CLI 類,它們像任何其他管理類一樣呈現給 C# 代碼。

建構 C# 到 C++ 裝置

此處使用的技術與我在編寫 C++/CLI 測試中介紹的并沒有太大差別。所有這些技術均使用相同類型的混合模式代碼。差別在于它們最終的用法。

第一步是建立新項目,該項目将包含您的裝置:

  1. 在解決方案資料總管中,右鍵單擊解決方案節點,單擊“添加”,然後單擊“新項目”。
  2. 在其他語言、Visual C++ 和 CLR 下,單擊“類庫”。
  3. 輸入要勇于該項目的名稱,然後單擊“确定”。
  4. 重複以上步驟以建立測試項目,進而添加引用和 include 檔案。

裝置類本身與測試類有些類似,但是不具有各種屬性(請參閱圖 6)。

圖 6 C# 到 C++ 測試裝置

  1. namespace MyCodeFixtures {
  2. public ref class MyCodeFixture {
  3. MyCodeFixture() {
  4. ~MyCodeFixture() {
  5. !MyCodeFixture() {
  6. int DoSomething(int val) {
  7. return m_pInstance->SomeValue(val);

請注意,沒有頭檔案!這是我最喜歡的 C++/CLI 功能之一。因為該類庫建構了托管程式集,并且有關類的資訊存儲為 .NET 類型的資訊,是以您不需要頭檔案。

該類也包含了析構函數和終結器。此處的析構函數并不是真正的析構函數。而在 IDisposable 接口中,編譯器會将析構函數重新編寫為 Dispose 方法的實作。是以,任何擁有析構函數的 C++/CLI 類都會實作 IDisposable 接口。

!MyCodeFixture 方法為終結器,垃圾收集器決定釋放該對象時會調用該方法,除非您之前已調用 Dispose 方法。您既可以采用 using 語句來控制嵌入式本機 C++ 對象的生存期,也可以讓垃圾收集器來處理生存期。有關此行為的詳細資訊,請通路 bit.ly/kW8knr 上的 MSDN 庫文章“析構函數語義更改”。

擁有 C++/CLI 裝置類後即可編寫類似圖 7 的 C# 單元測試。

圖 7 C# 單元測試系統

  1. using Microsoft.VisualStudio.TestTools.UnitTesting;
  2. using MyCodeFixtures;
  3. namespace MyCodeTests2 {
  4. publicclass UnitTest1 {
  5. publicvoid TestMethod1() {
  6. using (MyCodeFixture fixture = new MyCodeFixture()) {
  7. int result = fixture.DoSomething(1);
  8. Assert.AreEqual<int>(1, result);

我想使用 using 語句來明确控制裝置對象的生存期,而不是依賴垃圾收集器。這在測試方法中尤為重要,它能確定測試不與其他測試互動。

捕獲和報告代碼覆寫率

我在本文開頭處介紹的最後一部分為代碼覆寫率。我們團隊的目标是使代碼覆寫率能自動被建構伺服器捕獲,能釋出至 TFS 且易于擷取。

第一步是了解如何從運作的測試中捕獲 C++ 代碼覆寫率。在 Web 上搜尋時,我找到了 Emil Gustafsson 的一篇資訊豐富的部落格文章,标題為“使用 Visual Studio 2008 Team System 的本機 C++ 代碼覆寫率報告”(bit.ly/eJ5cqv)。此文章顯示了捕獲代碼覆寫率資訊所需的步驟。我将其轉換為 CMD 檔案,這樣就可以随時在我的開發計算機上運作該檔案,以捕獲代碼覆寫率資訊:

  1. "%VSINSTALLDIR%\Team Tools\Performance Tools\vsinstr.exe" Tests.dll /COVERAGE
  2. "%VSINSTALLDIR%\Team Tools\Performance Tools\vsperfcmd.exe" /START:COVERAGE /WaitStart /OUTPUT:coverage
  3. mstest /testcontainer:Tests.dll /resultsfile:Results.trx
  4. "%VSINSTALLDIR%\Team Tools\Performance Tools\vsperfcmd.exe" /SHUTDOWN

您将需要用包含測試的 DLL 實際名稱替換 Tests.dll。還需要準備要檢測的 DLL:

  1. 在解決方案資料總管視窗中,右鍵單擊測試項目。
  2. 單擊“屬性”。
  3. 選擇“調試配置”。
  4. 展開“配置屬性”,然後展開“連結器”并單擊“進階”。
  5. 将“配置檔案”屬性更改為“是(/PROFILE)”。
  6. 單擊“OK”(确定)。

這些步驟啟用了分析,您需要啟用該功能以實作程式集,進而捕獲代碼覆寫率資訊。

重構您的項目并運作 CMD 檔案。這将建立一個覆寫率檔案。将該覆寫率檔案加載至 Visual Studio,以確定可以從測試中捕獲代碼覆寫率。

在建構伺服器上執行這些步驟并将結果釋出至 TFS 需要一個自定義構模組化闆。TFS 構模組化闆存儲在版本控制中,并且它們屬于特定團隊項目。您将在每個團隊項目下找到名為“BuildProcessTemplates”的檔案夾,該檔案夾很可能擁有多個構模組化闆。

若要使用下載下傳中包含的自定義構模組化闆,請打開“源代碼控制資料總管”視窗。導航到團隊項目中的“BuildProcessTemplates”檔案夾,并確定已将其映射到您計算機的一個目錄。将 BuildCCTemplate.xaml 檔案複制到該映射位置。将該模闆添加至源代碼控制并将其簽入。

必須先将模闆檔案簽入,這樣才可在建構定義時使用這些檔案。

現在您已簽入構模組化闆,可以建立建構定義來運作代碼覆寫率。可以使用 vsperfmd 指令來收集 C++ 代碼覆寫率,如前所示。Vsperfmd 會偵聽所有檢測的可執行檔案的代碼覆寫率資訊,這些可執行檔案會随着 Vsperfmd 的運作而運作。是以,您不希望其他的檢測測試同時運作。您也應該確定僅有一個建構代理在計算機上運作,該建構代理将處理這些代碼覆寫率的運作。

我建立了一個會在夜間運作的建構定義。您可以通過以下步驟達到這一目的:

  1. 在“團隊資料總管”視窗中,展開您團隊項目的節點。
  2. 右鍵單擊“建構”,其為您團隊項目下的一個節點。
  3. 在“觸發器”部分,單擊“計劃”并選擇要運作代碼覆寫率的時間。
  4. 在“處理”部分,單擊調用頂部建構過程模闆部分中的“顯示詳細資訊”,然後選擇簽入到源代碼控制中的構模組化闆。
  5. 填寫其他必填部分并儲存。

添加測試設定檔案

建構定義也需要測試設定檔案。其為 XML 檔案,其中列出了要為其捕獲并釋出結果的 DLL。以下是為代碼覆寫率設定該檔案的步驟:

  1. 輕按兩下 Local.testsettings 檔案,然後打開“測試設定”對話框。
  2. 單擊左側清單中的“資料”和“診斷”。
  3. 單擊“代碼覆寫率”并選中複選框。
  4. 單擊清單上的“配置”按鈕。
  5. 選中包含您的測試(也包含測試所測試的代碼)的 DLL 旁的框。
  6. 取消選中準備就緒的檢測程式集,因為建構定義将處理該問題。
  7. 單擊“确定”和“應用”,然後單擊“關閉”。

如果您想建構多個解決方案或者有多個測試項目,則您将需要複制一個測試設定檔案,其包含應監視其代碼覆寫率的所有程式集的名稱。

若要完成此任務,請将測試設定檔案複制到您分支的根目錄下,并給定一個描述性名稱,如 CC.testsettings。編輯 XML。檔案将至少包含來自上述步驟中的一個 CodeCoverageItem 元素。您需要為要捕獲的每個 DLL 添加一個條目。請注意,路徑與項目檔案的位置而不是測試設定檔案的位置相關。将該檔案簽入源代碼控制中。

最後,您需要修改建構定義來使用以下測試設定檔案:

  1. 在“團隊資料總管”視窗中,展開您團隊項目的節點,然後展開“建構”。
  2. 輕按兩下之前建立的建構定義。
  3. 單擊“編輯建構定義”。
  4. 在“處理”部分,展開“自動化測試”,然後展開 1。測試程式集并單擊“TestSettings”檔案。單擊“…”按鈕,然後選擇我們之前建立的測試設定檔案。
  5. 儲存更改。

您可以通過右鍵單擊并選擇“排隊新建構”來測試該建構定義,進而立即啟動新建構。

報告代碼覆寫率

我建立了自定義 SQL Server Reporting Services 報告,其顯示了代碼覆寫率,如圖 8 所示(我模糊了實際項目的名稱以防止犯錯)。該報告使用 SQL 查詢來讀取 TFS 倉庫中的資料,并顯示 C++ 和 C# 代碼的組合結果。

使用 Visual Studio 和 TFS 進行 Agile C++ 開發和測試

圖 8 代碼覆寫率報告

在此我将不詳述此報告的工作方式,但是我想提醒您注意幾個方面。出于以下兩個原因,資料庫包含了來自 C++ 代碼覆寫率的太多資訊:測試方法代碼包括在結果中,标準 C++ 庫(在頭檔案中)包括在結果中。

  1. andCodeElementNamenotlike'std::%'
  2. andCodeElementNamenotlike'stdext::%'
  3. andCodeElementNamenotlike'`anonymous namespace'':%'
  4. andCodeElementNamenotlike'_bstr_t%'
  5. andCodeElementNamenotlike'_com_error%'
  6. andCodeElementNamenotlike'%Tests::%'