VisualStudio中的單元測試

来源:https://www.cnblogs.com/dino623/archive/2019/07/30/unittest_in_VisualStudio.html
-Advertisement-
Play Games

1. VisualStuio中的測試資源管理器、CodeLens和ReSharper "上一篇文章" 重溫了《單元測試的藝術》里提到的單元測試的技術及原則。這篇文章實踐使用VisualStudio 2019進行單元測試。 在VisualStudio中通常都會使用“測試資源管理器”進行單元測試。 Pr ...


1. VisualStuio中的測試資源管理器、CodeLens和ReSharper

上一篇文章重溫了《單元測試的藝術》里提到的單元測試的技術及原則。這篇文章實踐使用VisualStudio 2019進行單元測試。

在VisualStudio中通常都會使用“測試資源管理器”進行單元測試。

Professional和Enterprise版本可以使用CodeLens,這大大方便了測試的運行與調試。

但CodeLens的圖標常常刷不出來,一些第三方插件(如ReSharper)會更好用。

2. Live Unit Test

VisualStudio可以使用Live Unit Test(實時單元測試),這個功能需要Enterprise版本。

Live Unit Testing 是 Visual Studio 2017 中引入的一種技術。 進行代碼更改時,它會自動執行單元測試。

實時單元測試:

  • 讓你更有信心地對代碼進行重構和更改。 Live Unit Testing 在編輯代碼時自動執行所有受影響的測試,確保所做更改不會中斷測試。

  • 指示單元測試是否充分覆蓋代碼,並顯示未被單元測試覆蓋的代碼。 Live Unit Testing 以圖形方式實時描繪代碼覆蓋率,以便一眼就能看到每行代碼覆蓋的測試數,目和未被任何單元測試覆蓋的行。

Live Unit Testing是個很好的功能,唯一的障礙是,如果解決方案中包含了集成測試會導致Live Unit Testing響應變慢。解決方案是創建一個不包含集成測試項目的解決方案,或者在解決方案資源管理器中右鍵單擊想要排除的每個測試項目,然後依次選擇“實時測試” > “排除”,這樣Live Unit Test就不會對這些項目進行測試。

3. 代碼覆蓋率

還是Enterprise版本的功能,Visual Studio的代碼覆蓋率工具可以很直觀地查看到單元測試的代碼覆蓋率。

4. Microsoft Fakes

微軟有他自己的隔離框架Microsoft Fakes(在公司名稱後面加Fakes,這命名真是超爛)。不過Fakes不怎麼建議使用。

Fakes有兩種風格:

  • Stub(存根) 將類替換為可實現同一介面的小型替代項。

  • Shim(填充碼) 在運行時修改應用的編譯代碼,這樣就可以運行測試提供的墊片代碼,而不用執行指定的方法調用。 填充碼可用於替換對無法修改的程式集(如 .NET 程式集)的調用。

一般原則是,為在 Visual Studio 解決方案中進行的調用使用存根,併為對其他引用的程式集的調用使用填充碼。 這是因為在你自己的解決方案中,通過按照存根要求的方式定義介面來分離組件是一個很好的做法。 但是,外部程式集(如 System.dll)通常沒有單獨的介面定義,因此必須改用填充碼。

其他需要註意的事項還有:

  • 性能。 填充碼運行較慢,因為它們在運行時會重新編寫你的代碼。 存根沒有這項性能開銷,與虛方法運行的速度一樣快。

  • 靜態方法和密封類型方法。 你只能使用存根實現介面。 因此,存根類型不能用於靜態方法、非虛方法、密封虛方法、密封類型中的方法,等等。

  • 內部類型。 存根和填充碼都可用於可通過程式集特性 InternalsVisibleToAttribute 訪問的內部類型。

  • 私有方法。 如果方法簽名中的所有類型都是可見的,則填充碼可替換對私有方法的調用。 存根只能替換可見方法。

  • 介面和抽象方法。 存根提供了可用於測試的介面和抽象方法的實現。 填充碼無法檢測介面和抽象方法,因為它們沒有方法體。

但是由於不建議使用Fakes,所以基本上都會用NSub創建偽對象,Fakes的價值在於Shim,它有些別的隔離框架沒有的獨特功能。

下麵已LogAn項目為例講解Fakes的用法。首先在單元測試的引用列表右鍵選中LogAn項目,選擇“添加 Fakes 程式集”,然後重新生成方案,這時候可見到項目中多了LogAn.Fakes的引用,以及多了一些Fakes的文件。

使用Stub的單元測試代碼如下:

ICalculator calculator = new Fakes.StubICalculator
{
    AddInt32Int32 = (arg1, arg2) => 3
};

Assert.AreEqual(calculator.Add(1, 2), 3);

重溫一下NSub的相同功能:

_calculator = Substitute.For<ICalculator>();
_calculator.Add(1, 2).Returns(3);
Assert.AreEqual(_calculator.Add(1, 2), 3);

和NSub不同,Fakes提供的功能少了很多,不僅如此,每次更改項目都可能要重新添加Fakes引用(至少我在編譯伺服器上的項目老是因為Fakes出錯)。所以一般不建議使用Fakes做Stub的功能。但是官方文檔中外部程式集(如 System.dll)通常沒有單獨的介面定義,因此必須改用填充碼 這句話卻沒有錯,反正System.dll之類的第三方程式集又不可能經常改變,所以也沒有需要重新添加Fakes程式集這個煩惱。下麵介紹一下Shim的使用。

假設有一個類:

public static class Y2KChecker
{
    public static void Check()
    {
        if (DateTime.Now == new DateTime(2000, 1, 1))
            throw new ApplicationException("y2kbug!");
    }
}

由於它依賴於DateTime.Now,而假設我們沒辦法更改這段代碼,為了對它進行單元測試我們必須使用Shim破除對DateTime.Now的依賴。首先選中System引用並右鍵選擇添加Fake程式集,然後在測試代碼的ShimsContext中插入Shim:

using (ShimsContext.Create())
{
    // Arrange:
    System.Fakes.ShimDateTime.NowGet = () => new DateTime(2000, 1, 1);

    // Act and Assert::
    Assert.ThrowsException<ApplicationException>(Y2KChecker.Check);
}

如上面代碼所示,Shim可以偽造DateTime.Now的值,這對單元測試提供了極大的方便。

5. 結語

雖然Fakes中的Stub不好用,但Shim還是挺有趣的,我建可以同時使用NSub和Fakes里的Shim。善用VisualStudio的各種工具可以大大提升單元測試的效率,不過基本上這些工具都只在Enterprise版本中提供。

有趣的是MSTest自己也沒有用Fakes,很多時候都是用moq。(例如PlatformServiceProviderTests.cs)

另外VisualStudio還有一些有趣的工具輔助單元測試,例如walterlv的這篇博客(不再為命名而苦惱!使用 MSTestEnhancer 單元測試擴展,寫契約就夠了)介紹了一種更直觀的單元測試編寫方式,不放試一試:

6. 參考

測試工具 - Visual Studio Microsoft Docs

單元測試 - Visual Studio Microsoft Docs

用 Microsoft Fakes 隔離測試代碼 - Visual Studio Microsoft Docs

瞭解如何使用實時單元測試測試代碼 - Visual Studio Microsoft Docs

代碼覆蓋率測試 - Visual Studio Microsoft Docs


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 紙殼CMS現已支持自定義欄位,在不修改代碼的情況下,可以對系統中的一些模塊進行欄位的擴展,如頁面,文章、產品等。 ...
  • 我們想要達到的結果是,綁定多個Checkbox然後我們還可以獲取它是否被選中,其實很簡單,我們只要找到那幾個關鍵的對象就可以了。 下麵是Ui,其中定義了一個WrapPanel來存放CheckBox,還有兩個按鈕,用於測試相關功能。 在動態添加Checkbox中我們定義了一個CheckBox數組,此後 ...
  • 關於值類型和引用類型: 淺度複製(shallow copy)只複製值類型(char,int )的值,而對於引用類型不會複製,淺度複製可以通過派生於System.Object的MemberwiseClone()方法來完成,這是一個受保護的方法。因為他並沒有考慮引用類型成員,因此新對象的引用成員就會指向 ...
  • 1.記憶體配置 MemoryConfigurationProvider使用記憶體中集合作為配置鍵值對。若要激活記憶體中集合配置,請在ConfigurationBuilder的實例上調用AddInMemoryCollection擴展方法。可以使用IEnumerable<KeyValuePair<String ...
  • 錄製視頻也是一個很有意思的過程,一般需要提前準備好相關的提綱,以及整個思路的過程,在開始嘗試的時候,可能還會因為有些特殊問題,而不得不重來一遍,錄製視頻開始用的是Snagit的軟體,這個軟體對視頻的錄製效果還是不錯的,後來進一步瞭解並使用了OBS Studio的視頻錄製軟體,這個軟體是更專業的視頻錄... ...
  • abp(net core)+easyui+efcore實現倉儲管理系統目錄 ...
  • 通過abp(net core)+easyui+efcore實現倉儲管理系統——展現層實現增刪改查之控制器(六)至abp(net core)+easyui+efcore實現倉儲管理系統——展現層實現增刪改查之菜單與測試(九)四篇文章的學習,我們使用ASP.NET Core Mvc的常規的實現方式實現了... ...
  • 在C#中我們想要獲取字元串的拼音並不是那麼困難的,在網上看到很多都是特別笨的方式來實現,其實各有各的好處吧,如果使用了下方法方式,它不知道多音字,這就是一個問題。 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...