日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > C# >内容正文

C#

VSCode + xUnit 编写 C# 单元测试

發(fā)布時間:2023/12/20 C# 51 豆豆
生活随笔 收集整理的這篇文章主要介紹了 VSCode + xUnit 编写 C# 单元测试 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

概述

什么是單元測試?為什么要寫單元測試?如何寫一個單元測試?實話實說,寫單元測試是一件挺麻煩的事情,卻又是你在軟件開發(fā)的成長路上難以回避的一個問題。我個人在以前也并不喜歡單元測試,不過現(xiàn)在我的態(tài)度有所改觀了。如果本文所寫的內(nèi)容可以讓你理解單元測試的重要性,并且說服你在今后也開始嘗試編寫單元測試的話,那么這篇博文就是成功的。


轉(zhuǎn)自猴開發(fā)博客:VSCode + xUnit 編寫 C# 單元測試

一、什么是單元測試?

Having automated tests is a great way to ensure a software application does what its authors intend it to do. There are multiple types of tests for software applications. These include integration tests, web tests, load tests, and others. Unit tests test individual software components and methods. Unit tests should only test code within the developer’s control. They should not test infrastructure concerns. Infrastructure concerns include databases, file systems, and network resources.

以上是微軟在官方文檔《.NET Core 和 .NET Standard 中的單元測試》中對單元測試給出的描述。其中提到,單元測試用于測試個人軟件組件或方法,單元測試僅應(yīng)測試開發(fā)人員控件內(nèi)的代碼,它們不應(yīng)測試基礎(chǔ)結(jié)構(gòu)問題。 基礎(chǔ)結(jié)構(gòu)問題包括數(shù)據(jù)庫、文件系統(tǒng)和網(wǎng)絡(luò)資源。也就是說單元測試的被測目標必須足夠的“獨立”,進而測試代碼也應(yīng)足夠簡潔。

按我的理解來說,單元測試就是一項驗證一個類或方法是否能夠正常執(zhí)行并得到正確結(jié)果的測試工作,其中的類或方法就是被測試的單元。看完這些,你可能還是不能夠清晰地理解單元測試,不過不要緊,在后面的分析中,相信單元測試的形象將會在你的腦海中逐漸清晰。

二、為什么要寫單元測試?

實話實說,寫單元測試是一件挺麻煩的事情,我個人在以前也并不喜歡單元測試,不過現(xiàn)在我的態(tài)度有所改觀了。如果我之后寫的內(nèi)容可以讓你理解單元測試的重要性,并且說服你在今后也開始嘗試單元測試,那么這一小節(jié)就是成功的。

首先,在實際的開發(fā)過程中施行單元測試是一項非常有意義的事情,它既可以保證我們程序的健壯性,也可以在很大程度上幫助我們寫出更穩(wěn)定、低耦合的代碼,進而在維護期保護了應(yīng)用程序迭代更新的安全性與需求變動時的可拓展性。這是因為,一個優(yōu)秀完備的單元測試往往能夠覆蓋類和方法的各種邊界條件,進而在源頭處破滅了許多bug誕生的夢想,由此各個單元都能夠穩(wěn)定正確地執(zhí)行,整個程序的健壯性便得到了保障。

考慮一個簡單的例子,你正在寫一個求整型數(shù)組中最大元素的方法,下面是其實現(xiàn)代碼:

namespace MyAlgorithm {public class ArrayService{public static int MaxItemValue(int[] arr){var maxValue = arr[0];foreach(var item in arr){if(item>maxValue) maxValue = item;}return maxValue;}} }

通常,如果你直接著手實現(xiàn)的細節(jié)而開始寫代碼的話,你將難免忘記考慮一些邊界條件,而程序在各種環(huán)境運行的過程中,情況往往豐富多變,這就導(dǎo)致所寫出的程序往往在調(diào)試期間可以“正確運行”,可是一旦投入使用,各種靈異錯誤就接踵而來。上面的代碼段作為一個錯誤的例子,相信你不難看出是有明顯的問題的。在通常的輸入下,它可以正常的執(zhí)行,可是如果輸入的數(shù)組為空呢?那就糟糕了,你絕對不想看到編譯器給你拋出一堆鮮紅的Errors,更不希望讓用戶看到錯誤警告。可是當(dāng)你養(yǎng)成寫單元測試的習(xí)慣時,你就會自然地為測試單元有意地設(shè)計各種看似“不合理”的輸入,而一旦你的代碼通過了嚴苛而險惡的單元測試,恭喜你,這個可靠的單元可以被你貼上"合格"的標簽放心地使用了。

于此同時,單元測試幫助代碼更穩(wěn)定、低耦合是由于,一個與其它單元耦合度高又內(nèi)部復(fù)雜的類或方法,我們幾乎無法為其寫出一個簡明可行的單元測試,這就顯示地要求開發(fā)者對當(dāng)前過分復(fù)雜的“單元”進行拆分與解耦,以便為其書寫單元測試,這也就促使程序變得更加模塊化,更具可讀性了。這對于一直想要寫出更加優(yōu)秀代碼的你來講簡直是太棒了,不是嗎?

由此可以發(fā)現(xiàn),單元測試其實就是為組成我們程序的一個個小單元,可以是類或方法或是其它的組件,單獨編寫測試用例,以保證它們的正確性與可靠性。這既是單元測試的進一步闡述,也是你為什么要寫單元測試的原因。

三、如何創(chuàng)建單元測試?

了解了單元測試及其必要性,下面就來看一看如何寫一個單元測試吧。在不同的編輯器或集成開發(fā)環(huán)境中為代碼編寫單元測試的方法不盡相同,本節(jié)中將演示如何在 VSCode 中使用 xUnit 為 C# 項目編寫一個簡單的單元測試。這一節(jié)演示將分為四個部分:創(chuàng)建項目、編寫一個示例類、為示例類創(chuàng)建單元測試類,以及在單元測試類中為示例類的一個成員函數(shù)編寫單元測試代碼。

在演示中,我們將創(chuàng)建一個用于數(shù)字計算的 NumberCacluation 類,并實現(xiàn)該類的一個整數(shù)求和函數(shù) add(),最后為該類創(chuàng)建單元測試類并為其成員函數(shù) add() 編寫單元測試代碼。如果你使用的是 Visual Studio,那么網(wǎng)上也有很多針對 VS 的單元測試編寫指導(dǎo),在此就不多提了。下面就讓我們開始吧!

1.創(chuàng)建項目

  • 在 VSCode 中打開一個文件夾,本例中新建并打開文件夾 MyProject。

  • 打開終端,執(zhí)行 dotnet new sln 來新建一個解決方案,此時你在 MyProject 文件夾中將得到一個 MyProject.sln 解決方案文件。

  • 在 MyProject 文件夾下新建一個目錄 MyMath,作為我們的數(shù)學(xué)計算類庫文件夾。

  • 在終端中進入 MyMath 目錄,執(zhí)行 dotnet new classlib 來對此類庫文件夾進行初始化,你將在 MyMath 文件夾中得到 MyMath.csproj 與一個默認的 cs 文件 Class1.cs,在此我們將其改名為 NumberCalculation.cs,其代碼結(jié)構(gòu)如下:

    using System;namespace MyMath.Number {public class NumberCalculation{} }
  • 最后,在終端中回到 MyProject 目錄,執(zhí)行 dotnet sln add .\MyMath\MyMath.csproj 來將 MyMath 添加到解決方案當(dāng)中。至此,我們就完成了項目的創(chuàng)建。

  • 2.編寫示例類

    打開 MyMath 目錄下的 NumberCalculation.cs 文件,下面我們?yōu)槠渚帉懸粋€靜態(tài)函數(shù),用于求解兩個整數(shù)求和計算的結(jié)果,實現(xiàn)代碼非常簡單,下面是完整的代碼:

    using System;namespace MyMath.Number {public class NumberCalculation{public static int add(int a, int b){return a + b;}} }

    3.創(chuàng)建單元測試

  • 我們先在終端 MyProject 目錄下新建一個文件夾:MyMath.Tests,這個文件夾中用于存放 MyMath 的相關(guān)單元測試文件。

  • 在終端中進入 MyMath.Tests 目錄,執(zhí)行 dotnet new xunit 來初始化 xunit,此命令會創(chuàng)建將 xUnit 用作測試庫的測試項目。你將得到 MyMath.csproj 和 一個默認的單元測試類 UnitTest1.cs,我們將其改名為 MyMath.Tests.Number.cs,代碼結(jié)構(gòu)如下(記得為其手動添加 NumberCalculation 的命名空間引用using MyMath.Number;):

    using System; using Xunit;namespace MyMath.Tests.Number {public class UnitTest1{[Fact]public void Test1(){}} }
  • 在終端 MyMath.Tests 目錄下執(zhí)行 dotnet add reference ..\MyMath\MyMath.csproj 來將 MyMath 引入到我們的單元測試項目中來。

  • 最后在終端中回到 MyProject 目錄,執(zhí)行 dotnet sln add .\MyMath.Tests\MyMath.Tests.csproj 來將 MyMath.Tests 添加到解決方案中。至此,我們完成了 MyMath 類單元測試的創(chuàng)建與一些初始設(shè)置。

  • 4. 編寫單元測試

    打開 MyMath.Tests 目錄下的 UnitTest1.cs 文件,編寫如下四個測試用例:

    using System; using Xunit; using MyMath.Number; namespace MyMath.Tests.Number {public class UnitTest1{[Fact]public void Test1(){Assert.True(NumberCalculation.add(0,2)==2, "0 + 2 Should be 2");}[Fact]public void Test2(){Assert.True(NumberCalculation.add(1,2)==3, "1 + 2 Should be 3");}[Fact]public void Test3(){Assert.True(NumberCalculation.add(-1,2)==1, "-1 + 2 Should be 1");}[Fact]public void Test4(){Assert.True(NumberCalculation.add(-1,-2)==-3, "-1 + -2 Should be -3");}} }

    這樣,我們就完成了 add() 方法的簡單單元測試示例。其中 [Fact] 標記指明下面的方法為測試方法,Assert.True() 函數(shù)中的第一項參數(shù)為實際值,其預(yù)期值為 True,當(dāng)實際值與預(yù)期值一致時,該測試就可以通過,否則該測試不能通過,并將在終端中將參數(shù)二作為錯誤信息輸出顯示。

    最后,在終端中 MyMath.Tests 文件夾下執(zhí)行 dotnet test 即可運行單元測試。顯然,我們之前編寫的函數(shù)是可以正確計算所給用例的加法的,因此終端輸出了如下信息:

    PS C:\...\MyProject> dotnet test 已開始生成,請等待... Skipping running test for project C:\...\MyProject\MyMath\MyMath.csproj. To run tests with dotnet test add "<IsTestProject>true<IsTestProject>" property to project file. 完成的生成。C:\...\MyProject\MyMath.Tests\bin\Debug\netcoreapp2.2\MyMath.Tests.dll 的測試運行(.NETCoreApp,Version=v2.2) Microsoft (R) 測試執(zhí)行命令行工具版本 15.9.0 版權(quán)所有 (C) Microsoft Corporation。保留所有權(quán)利。正在啟動測試執(zhí)行,請稍候...總測試: 4。已通過: 4。失敗: 0。已跳過: 0。 測試運行成功。 測試執(zhí)行時間: 2.4093 秒

    如果我們的 add() 方法編寫有誤,例如將 return a + b; 錯誤地修改為 return b;,再次執(zhí)行 dotnet test 將得到如下信息:

    PS C:\...\MyProject> dotnet test 已開始生成,請等待... Skipping running test for project C:\...\MyProject\MyMath\MyMath.csproj. To run tests with dotnet test add "<IsTestProject>true<IsTestProject>" property to project file. 完成的生成。C:\...\MyProject\MyMath.Tests\bin\Debug\netcoreapp2.2\MyMath.Tests.dll 的測試運行(.NETCoreApp,Version=v2.2) Microsoft (R) 測試執(zhí)行命令行工具版本 15.9.0 版權(quán)所有 (C) Microsoft Corporation。保留所有權(quán)利。正在啟動測試執(zhí)行,請稍候... [xUnit.net 00:00:01.04] MyMath.Tests.Number.UnitTest1.Test4 [FAIL] [xUnit.net 00:00:01.07] MyMath.Tests.Number.UnitTest1.Test2 [FAIL] [xUnit.net 00:00:01.07] MyMath.Tests.Number.UnitTest1.Test3 [FAIL] MyMath.Tests.Number.UnitTest1.Test4 個失敗 錯誤消息:-1 + -2 Should be -3 Expected: True Actual: False 堆棧跟蹤:at MyMath.Tests.Number.UnitTest1.Test4() in C:\...\MyProject\MyMath.Tests\UnitTest1.cs:line 26 MyMath.Tests.Number.UnitTest1.Test2 個失敗 錯誤消息:1 + 2 Should be 3 Expected: True Actual: False 堆棧跟蹤:at MyMath.Tests.Number.UnitTest1.Test2() in C:\...\MyProject\MyMath.Tests\UnitTest1.cs:line 16 MyMath.Tests.Number.UnitTest1.Test3 個失敗 錯誤消息:-1 + 2 Should be 1 Expected: True Actual: False 堆棧跟蹤:at MyMath.Tests.Number.UnitTest1.Test3() in C:\...\MyProject\MyMath.Tests\UnitTest1.cs:line 21總測試: 4。已通過: 1。失敗: 3。已跳過: 0。 測試運行失敗。 測試執(zhí)行時間: 2.4545 秒

    可以看到,終端中明確輸出了未通過測試的用例及其錯誤信息,這將幫助你很快地定位并修復(fù)相關(guān)錯誤。

    四、優(yōu)化你的單元測試

    寫出一個單元測試不是一件難事,但是寫出一個好的單元測試也不是一件容易的事。就上一小結(jié) 編寫單元測試 中給出的測試代碼就是極度糟糕的代碼的典范。為了使用 xUnit 寫出基本還不錯的測試代碼,你需要了解 xUnit 的一些其它屬性。例如 [Theory] 表示執(zhí)行相同的代碼,但是使用不同的輸入?yún)?shù)用來測試,并使用 [InlineData] 來指定這些參數(shù)的輸入值。

    由此改進后的單元測試代碼如下:

    public class UnitTest1{[Theory][InlineData(0,2,2)][InlineData(1,2,3)][InlineData(-1,2,1)][InlineData(-1,-2,-3)]public void Test1(int a, int b, int excepted){Assert.True(NumberCalculation.add(a,b)==excepted, $"{a} + {b} Should be {excepted}");}}

    同時,為了確保單元測試的正確性與輕便性,應(yīng)當(dāng)選取盡可能少且具有代表性的參數(shù)作為測試用例,否則過多的測試用例不僅有可能被人為地賦予錯誤期望造成單元測試失效(例如不小心將 [InlineData(-1,-2,-3)] 的期望輸出寫成了 3),也將增加每一次單元測試的時間開銷。

    針對 .NET Core 和 .NET Standard 單元測試的最佳做法與工程實施規(guī)范,微軟在其官方文檔中給出了詳盡的說明,這些條款在單元測試的編寫中具有很好的指導(dǎo)意義,可以幫助你寫出更具規(guī)范與更易讀的單元測試:《.NET Core 和 .NET Standard 單元測試最佳做法》。

    五、參考文章

    • .NET Core 和 .NET Standard 中的單元測試
    • 使用 dotnet test 和 xUnit 在 .NET Core 中進行 C# 單元測試
    • The Explicit Dependencies Principle states

    總結(jié)

    以上是生活随笔為你收集整理的VSCode + xUnit 编写 C# 单元测试的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。