.NET 項目中的單元測試

2021-02-16 amazingdotnet
.NET 項目中的單元測試Intro

「不會寫單元測試的程式設計師不是合格的程式設計師,不寫單元測試的程式設計師不是優秀的工程師。」

—— 一隻想要成為一個優秀程式設計師的渣逼程序猿。

那麼問題來了,什麼是單元測試,如何做單元測試。

單元測試單元測試的定義

按照維基百科上的說法,單元測試(Unit Testing)又稱為模塊測試, 是針對程序模塊(軟體設計的最小單位)來進行正確性檢驗的測試工作。程序單元是應用的最小可測試部件。在面向對象編程中,最小單元就是方法,包括基類、抽象類、或者派生類(子類)中的方法。按照通俗的理解,一個單元測試判斷某個特定場條件下某個特定方法的行為,如斐波那契數列算法,冒泡排序算法。

單元測試(unit testing),是指對軟體中的最小可測試單元進行檢查和驗證。對於單元測試中單元的含義,一般來說,要根據實際情況去判定其具體含義, 如C語言中單元指一個函數,Java裡單元指一個類,圖形化的軟體中可以指一個窗口或一個菜單等。總的來說,單元就是人為規定的最小的被測功能模塊。單元測試是在軟體開發過程中要進行的最低級別的測試活動,軟體的獨立單元將在與程序的其他部分相隔離的情況下進行測試。

—— 百度百科 http://baike.baidu.com/view/106237.htm

單元測試的好處

它是一種驗證行為

程序中的每一項功能都是測試來驗證它的正確性。

它是一種設計行為

編寫單元測試將使我們從調用者觀察、思考。特別是先寫測試(test-first),迫使我們把程序設計成易於調用和可測試的,有利於程序的解耦和模塊化。

它是一種編寫文檔的行為

單元測試是一種無價的文檔,它是展示函數或類如何使用的最佳文檔。這份文檔是可編譯、可運行的,並且它保持最新,永遠與代碼同步。

它具有回歸性

自動化的單元測試避免了代碼出現回歸,編寫完成之後,可以隨時隨地的快速運行測試。

高效

自動化的單元測試節省了開發上調試BUG的時間,絕大多數BUG可以通過單元測試測試出來,並且可以減少測試人員的測試時間。有時候通過寫單元測試能夠更好的完善自己程序的邏輯,讓程序變得更加美好。

—— 單元測試的優點 http://jingyan.baidu.com/article/d713063522ab4e13fdf47533.html

單元測試的原則在內存中運行,沒有外部依賴組件(比如說真實的資料庫,真實的文件存儲等).NET 中的測試框架

現在比較流行的測試框架包括微軟的 MS Test(VS Test)、NUnit、XUnit

MS Test

VS單元測試的主要類:Assert、StringAssert、CollectionAssert,具體可參照 MSDN介紹

有些時候我們需要對測試的方法用到的數據或配置進行初始化,有幾個特殊的測試方法。

如果需要針對測試中的所有虛擬用戶迭代僅執行一次初始化操作,請使用 TestInitializeAttribute。

初始化方法的運行順序如下:

用 AssemblyInitializeAttribute 標記的方法。用 ClassInitializeAttribute 特性標記的方法。用 TestInitializeAttribute 特性標記的方法。用 TestMethodAttribute 特性標記的方法。

使用 VS Test 的時候,首先我們需要標記測試方法所在類 TestClass,測試方法標記為 TestMethod

NUnit

NUnit 測試框架使用方法與 MS Test 類似

有一些是 NUnit 中的,但是MS Test框架中是沒有的:

Assert.IsNaN/Assert.IsEmpty/Assert.IsNotEmpty/Assert.Greater/Assert.GreaterOrEqual 等

想要同時使用 VS Test 和 NUnit 的話可以使用宏來區分不同的測試框架,例如:

#if !NUNIT
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Category = Microsoft.VisualStudio.TestTools.UnitTesting.DescriptionAttribute;
#else
using NUnit.Framework;
using TestClass = NUnit.Framework.TestFixtureAttribute;
using TestMethod = NUnit.Framework.TestAttribute;
using TestInitialize = NUnit.Framework.SetUpAttribute;
using TestCleanup = NUnit.Framework.TearDownAttribute;
using TestContext = System.Object;
using ClassCleanup = NUnit.Framework.TestFixtureTearDownAttribute;
using ClassInitialize = NUnit.Framework.TestFixtureSetUpAttribute;
#endif

從上面可以看得出來 nunit 很多東西和 vs test 是很類似的,聲明測試類,測試方法,初始化方法等

XUnit

XUnit 是另一個測試框架,個人覺得 XUnit 測試更加簡潔一些,初始化和釋放資源不需要標記單獨的方法,初始化直接放在構造方法裡,資源釋放實現 IDisposable 接口,在 Dispose 方法中進行測試的清理工作即可,相比 ms test(vs test)和 NUnit,我覺得 Xunit 更方便一些,並且對於 Assert ,xunit 更簡潔,例如:在 ms test 中的 Assert.IsNull(null);/Assert.IsTrue(1 == 1); 在 xunit 中則是 Assert.Null(null);/Assert.True(1 == 1);,雖然看上去差不多,但是寫的多了就會覺得 xunit 更簡潔一些。

xunit 不需要對測試方法所在類型標記 TestClass ,只需要在測試方法上標記 Fact 或者使用數據驅動的 Theory

XUnit 的基本使用

使用 XUnit 來寫測試方法可以使得測試代碼更為簡潔,更加簡單,推薦使用 xunit 來測試自己的代碼

測試示例:

public class ResultModelTest
{
    [Fact]
    public void SuccessTest()
    {
        var result = ResultModel.Success();
        Assert.Null(result.ErrorMsg);
        Assert.Equal(ResultStatus.Success, result.Status);
    }

    [Theory]
    [InlineData(ResultStatus.Unauthorized)]
    [InlineData(ResultStatus.NoPermission)]
    [InlineData(ResultStatus.RequestError)]
    [InlineData(ResultStatus.NotImplemented)]
    [InlineData(ResultStatus.ResourceNotFound)]
    [InlineData(ResultStatus.RequestTimeout)]
    public void FailTest(ResultStatus resultStatus)
    {
        var result = ResultModel.Fail("test error", resultStatus);
        Assert.Equal(resultStatus, result.Status);
    }
}

最基本的測試,使用 Fact 標記測試方法,使用 Assert 來斷言自己對結果的預期

可以使用 Theory 來自己指定一批數據來進行測試,來實現測試數據驅動測試,簡單的數據可以通過 InlineData 直接指定,也可以使用 MemberData 來指定一個方法來返回用於測試的數據,也可以自定義一個繼承於 DataAttribute 的 Data Provider

More

我覺得在我們開發過程中測試是非常重要的一部分,高質量項目的一個重要指標就是測試覆蓋率,,一個高質量的開源項目一定是有比較完善的測試項目的,所以對於測試非常有必要了解一下,並將它集成到自己的項目中持續保證項目的高質量,同時完善的測試對於項目重構也是非常有好處的,能夠很大程度上檢測是否有發生一些破壞性的變更。

總而言之,開始寫單元測試吧,為成為一個優秀的工程師而努力~~

ReferenceMSDN - Microsoft.VisualStudio.TestTools.UnitTestingVS2012 Unit Test 個人學習匯總(含目錄)https://stackoverflow.com/questions/261139/nunit-vs-mbunit-vs-mstest-vs-xunit-nethttps://docs.microsoft.com/en-us/dotnet/core/testing/unit-testing-with-dotnet-test

相關焦點

  • 單元測試可測試程式設計師代碼編寫的正確性,如何使用VS2019測試項目
    在Visual Studio 2019中內置了多種測試工具,這裡我們使用基於.NET Framework的單元測試項目來測試代碼。單元測試是以項目的方式存在的,與應用程式項目結合在一起對代碼進行單元測試,保證每開發一個方法都是經過測試的合格程序。
  • 解讀Android官方MVP項目單元測試
    Google官方這次伴隨MVP架構同步推出的單元測試用例,確實值得好好研究。本文作者geniusmart,對Android單元測試一直頗有研究,早前也曾給我投稿過 Android單元測試最佳實踐之Robolectric3.0 一文,沒看過的同學可以移步閱讀。
  • 如何對機器學習做單元測試
    我在谷歌Brain學到的一個主要原則是,單元測試可以決定算法的成敗,可以為你節省數周的調試和訓練時間。然而,在如何為神經網絡代碼編寫單元測試方面,似乎沒有一個可靠的在線教程。即使是像OpenAI這樣的地方,也只是通過盯著他們代碼的每一行,並試著思考為什麼它會導致bug來發現bug的。顯然,我們大多數人都沒有這樣的時間,所以希望本教程能夠幫助你開始理智地測試你的系統!
  • JUnit測試單元框架
    他是用於單元測試框架體系xUnit的一個實例(用於java語言)。主要用於白盒測試,回歸測試。  junit安裝步驟  1、在http://download.sourceforge.net/junit/ 中下載JUnit包並將Junit壓縮包解壓。  2、添加CLASSPATH環境變量.
  • Android單元測試——初探
    本文主要包含以下內容:什麼是單元測試為什麼需要進行單元測試如何進行單元測試什麼是單元測試首先總結一下什麼是單元測試,單元測試中的單元在Android或Java中可以理解為某個類中的某一個方法,因此單元測試就是針對Android或Java中某個類中的某一個方法中的邏輯代碼進行驗證即測試該方法是不是可以正常工作
  • 單元測試的藝術
    集成測試:集成測試是對一個工作單元進行的、使用該單元的一個或多個真實依賴(例如時間、網絡、資料庫、線程或隨機數生成器等)而對被測試的工作單元沒有完全的控制的測試。4. 單元測試框架:單元測試框架為開發者提供了類庫,包括:提供一個測試運行器,用於發現代碼中的測試、自動運行測試、運行期間顯示狀態、用命令行自動化,查看測試運行結果。
  • 這3個C#單元測試工具,到底誰才是王者?
    單元測試(unit testing),是指對軟體中的最小可測試單元(函數/模塊/類)進行檢查和驗證。單元測試是在軟體開發過程中要進行的最低級別的測試活動,軟體的獨立單元將在與程序的其他部分相隔離的情況下進行測試。單元測試從長期來看,可以提高代碼質量,減少維護成本,降低重構難度。
  • cmake-gtest單元測試
    隨著開發人員對CMake工具的應用,測試同學自然也要學習使用CMake工具輔助進行單元測試。最近接手一個新項目從零開始測試,就將使用CMake工具輔助gtest單元測試的基本步驟簡單記錄下來。 準備工作下載gtest的安裝包(帶有cmake編譯功能的版本)。
  • Android單元測試與模擬測試詳解
    【威哥說】 測試驅動式編程(Test-Driven-Development)在RoR中已經是非常普遍的開發模式,是一種十分可靠、優秀的編程思想,可是在
  • 使用MockMVC進行Controller單元測試
    引入由於MockMVC是Spring框架自帶的測試組件,因此只要在項目中引入spring-boot-starter-test
  • Spring Boot 單元測試
    一、 單元測試的概念概念:單元測試(unit testing),是指對軟體中的最小可測試單元進行檢查和驗證。在Java中單元測試的最小單元是類。單元測試是開發者編寫的一小段代碼,用於檢驗被測代碼的一個很小的、很明確的功能是否正確。執行單元測試,就是為了證明這 段代碼的行為和我們期望是否一致。
  • 聊聊單元測試
    還有一種情況是,寫代碼的時候並沒有考慮這代碼要怎麼測,因此寫完了以後發現寫單元測試很難,沒有現成的測試入口。這時候項目交付的deadline又快到了,唉,要不先放著改天再寫吧。當然我們都知道,這個改天大概率再也不會做。我們有一萬個理由可以不做單元測試。但是這就好比,組裝一架飛機不用測試各個零件的運作是否符合預期,直接讓它飛起來再看有哪些問題。
  • Android單元測試實踐
    為什麼要引入單元測試  一般來說我們都不會寫單元測試,為什麼呢?因為要寫多餘的代碼,而且還要進行一些學習,入門有些門檻,所以一般在工程中都不會寫單元測試。那麼為什麼我決定要寫單元測試。  這篇文章看完並不會讓你完全掌握單元測試,但是會給你在單元測試的開始有一個好的指引  大大提高工作效率  單元的概念比較模糊,可以是一個方法,可以是一個時機,但是不是一整套環節,一整套環節那就是集成測試了。為什麼說大大提高了工作效率。
  • 3個C 單元測試工具,到底誰才是王者?
    ,是指對軟體中的最小可測試單元(函數/模塊/類)進行檢查和驗證。單元測試是在軟體開發過程中要進行的最低級別的測試活動,軟體的獨立單元將在與程序的其他部分相隔離的情況下進行測試。單元測試從長期來看,可以提高代碼質量,減少維護成本,降低重構難度。但是從短期來看,加大了工作量,對於進度緊張的項目中的開發人員來說,可能會成為不少的負擔。
  • 單元測試常用的方法
    單元測試   單元測試(unit testing),是指對軟體中的最小可測試單元進行檢查和驗證。對於單元測試中單元的含義,一般來說,要根據實際情況去判定其具體含義,如C語言中單元指一個函數,Java裡單元指一個類,圖形化的軟體中可以指一個窗口或一個菜單等。
  • .NET 程序集單元測試工具 SmokeTest 應用指南
    一般地我們使用腳本來實現Smoke Test的自動化,可借用虛擬機的snapshot機制來保證乾淨的環境來進行Smoke Test,然後將測試好的程序集成到Continous build或daily build中。 冒煙測試是指一種基本功能測試,是從硬體測試借鑑過來的。進行硬體測試時,首先需要給硬體加電,如果一加電電路燒了冒煙,後續的測試當然進行不去了,也就是能加電是後面測試的前提條件。
  • Github上優秀的.NET Core項目
    Omnisharp - 開源項目系列,每個項目都有一個目標:在您選擇的編輯器中實現出色的.NET體驗。SharpDevelop - SharpDevelop是一個免費的集成開發環境(IDE),適用於Microsoft.NET平臺上的C#,VB.NET,Boo,IronPython,IronRuby和F#項目。
  • Spring Boot 的單元測試和集成測試
    學習如何使用本教程中提供的工具,並在 Spring Boot 環境中編寫單元測試和集成測試。1. 概覽 本文中,我們將了解如何編寫單元測試並將其集成在 Spring Boot 環境中。你可在網上找到大量關於這個主題的教程,但很難在一個頁面中找到你需要的所有信息。我經常注意到初級開發人員混淆了單元測試和集成測試的概念,特別是在談到 Spring 生態系統時。
  • 關於單元測試體系結構的一些心得
    從上面列出的好處中可以明顯看出,採用適當的自動化測試策略很合適,可以幫助減輕軟體項目中的風險。在此測試中,組件將一個項目添加到文件存儲中,但實際上並不擔心操作是成功還是失敗(例如,日誌文件),因此,我們決定以「虛擬」方式模擬該操作。現在,假設稍後需求發生變化,並且組件需要確保在繼續操作之前通過從文件存儲中讀取文件來創建文件,這迫使我們更新模擬的行為以使測試通過。
  • 未名企鵝極客|軟體單元測試的基本原則
    單元測試的粒度要根據實際情況判定,可能是類、方法等,在面向對象編程中,通常認為最小的單元就是方法。 在很多人看來,快速完成業務功能開發才是王道,如果開發工程師說需要額外的時間來寫單元測試,並因此延長項目工期,估計有些項目經理就按捺不住了。其實單元測試是一件有情懷、有技術素養、有長遠收益的工作,它是保證項目質量和效率的重要手段之一。