单元测试(二)基本使用争议篇
介紹
常用的單元測試是測試方法、API等,下面我們來演示一下Xunit測試框架的簡單使用,有些是為了演示而寫的單元測試。
最下面有反轉,一定要看到最后
操作
創建單元測試項目
本次文章還在原來項目的基礎上進行操作,右鍵解決方案添加單元測試項目
img選擇框架版本為.Net 5.0
img單元測試項目創建完成。然后引用我們的包
<Project?Sdk="Microsoft.NET.Sdk"><PropertyGroup><TargetFramework>.NETCoreApp,Version=v5.0</TargetFramework><IsPackable>false</IsPackable></PropertyGroup><ItemGroup><PackageReference?Include="Microsoft.AspNetCore.TestHost"?Version="5.0.10"?/><PackageReference?Include="Microsoft.NET.Test.Sdk"?Version="16.9.4"?/><PackageReference?Include="xunit"?Version="2.4.1"?/><PackageReference?Include="xunit.runner.visualstudio"?Version="2.4.3"><IncludeAssets>runtime;?build;?native;?contentfiles;?analyzers;?buildtransitive</IncludeAssets><PrivateAssets>all</PrivateAssets></PackageReference><PackageReference?Include="coverlet.collector"?Version="3.0.2"?/></ItemGroup><ItemGroup><ProjectReference?Include="..\Net5ByDocker\Net5ByDocker.csproj"?/></ItemGroup></Project>TargetFramework:指定測試項目的目標框架
IsPackable:設置是否允許打包單元測試項目
xunit:該xunit包引入了三個子包,其中包括大多數開發人員想要的功能:(xunit.core測試框架本身)、 xunit.assert(包含Assert類的庫)和xunit.analyzers(使 Roslyn 分析器能夠檢測單元測試和 xUnit.net 可擴展性的常見問題)
包xunit.runner.visualstudio和Microsoft.NET.Test.Sdk 是能夠在 Visual Studio 中運行測試項目以及使用 dotnet test.
coverlet.collector:該coverlet.collector包允許收集代碼覆蓋率。如果您不打算收集代碼覆蓋率,則應刪除此包引用。
如果想使用MSTest框架,那么只需要在需要進行測試的方法上面點擊右鍵,創建單元測試
img點擊確定后將會為我們創建一個單元測試的應用程序,關于User控制器的單元測試我們就寫在這個里面
img這里我們并不使用MSTest進行測試。
創建基類文件BaseTest
public?class?BaseTest {protected?readonly?ITestOutputHelper?Output;public?BaseTest(ITestOutputHelper?output){Output?=?output;}public?string?SerializeObject(object?obj){JsonSerializerSettings?settings?=?new?JsonSerializerSettings{Formatting?=?Formatting.Indented,ContractResolver?=?new?CamelCasePropertyNamesContractResolver()};return?JsonConvert.SerializeObject(obj,?settings);} }///?<summary> ///?構建webhost ///?</summary> public?class?BaseWebHostTest?:?BaseTest {protected?readonly?TestServer?Server;public?BaseWebHostTest(ITestOutputHelper?helper)?:?base(helper){var?service?=?Host.CreateDefaultBuilder().ConfigureWebHostDefaults(webBuilder?=>{webBuilder.UseStartup<Startup>();}).Build().Services;Server?=?new?TestServer(service);} }///?<summary> ///?只是測試控制器Api ///?</summary> public?class?BaseHostTest?:?BaseTest {protected?readonly?TestServer?Server;public?BaseHostTest(ITestOutputHelper?helper)?:?base(helper){Server?=?new?TestServer(WebHost.CreateDefaultBuilder().UseEnvironment("Development")//測試使用.UseStartup<Startup>());} }測試API
就以演示獲取用戶信息為例,我們測試調用接口后是否返回狀態碼為200
編寫構造函數并賦值HttpClient
public?UserControllerTests(ITestOutputHelper?helper)?:?base(helper) {Client?=?Server.CreateClient();//var?token?=?"";?//?可以對HttpClient進行一些自定請求頭等操作//Client.DefaultRequestHeaders.Authorization?=?new?System.Net.Http.Headers.AuthenticationHeaderValue("Bearer",?token); }public?HttpClient?Client?{?get;?}測試
[Fact()] public?async?Task?Get_User_ReturnOk() {//Arrange??賦值區域//Actvar?response?=?await?Client.GetAsync("api/user/getlist");//AssertAssert.Equal(HttpStatusCode.OK,?response.StatusCode);Output.WriteLine(await?response.Content.ReadAsStringAsync()); }寫單元測試一般有三個步驟:Arrange,Act 和 Assert。
Arrange 是準備階段,這個階段是準備工作,比如模擬數據、初始化對象等;
Act 是行為階段,這個階段是用準備好的數據去調用要測試的方法;
Assert 是斷定階段,就是把調用目標方法返回的值和預期的值進行比較,如果和預期一致說明測試通過,否則為失敗。
點擊方法名字右鍵運行測試或者調試測試
img測試方法
比如我們去對IUserService里面的GetListAsync做單元測試,繼承自公共類,通過依賴注入獲取IUserService服務
public?class?UserServiceTest?:?BaseWebHostTest {private?readonly?IUserService?_userService;public?UserServiceTest(ITestOutputHelper?helper)?:?base(helper){_userService?=?Server.Services.GetRequiredService<IUserService>();}[Fact]public?async?Task?GetUser_ReturnOk(){//Arrange:準備階段?//Act:行為階段var?response?=?await?_userService.GetListAsync();//Assert:斷言階段Assert.NotNull(response);Output.WriteLine(JsonConvert.SerializeObject(response));} }點擊方法名字右鍵運行測試或調試測試
img單元測試成功
并行運行測試
在Xunit的2.x版本以后支持并行運行測試。這樣子相比如之前可以更好利用服務器性能。
新建測試類RunnerTimeTest,
public?class?RunnerTimeTest {[Fact]public?void?Test1(){Thread.Sleep(2000);}[Fact]public?void?Test2(){Thread.Sleep(3000);} }我們猜一下運行該測試類的話需要耗時多少?2s?3s?
img通過這個結果我們可以得出來一個測試類內并不是并行執行的。默認情況下每一個測試類都是一個唯一的測試集合,同一個測試類的測試不會彼此并行運行。那么我們將這兩個測試方法分別放入不同的測試類中
public?class?RunnerTimeTest {[Fact]public?void?Test1(){Thread.Sleep(2000);} }public?class?RunnerTimeTest2 {[Fact]public?void?Test2(){Thread.Sleep(3000);} }運行查看效果
img可以得到不同的測試類之間是并行執行的。
批評
這個是我理解的單元測試樣子,但是經過同事的嚴厲批評,我知道了應該使用單一變量原則,控制一處不同,其他變量保持相同,而不是像該文章一樣,依賴項不可控。
資料
命令行創建單元測試項目:https://xunit.net/docs/getting-started/netcore/cmdline
ASP.NET Core單元測試:https://www.cnblogs.com/willick/p/aspnetcore-unit-tests-with-xunit.html
并行運行測試:https://xunit.net/docs/running-tests-in-parallel
總結
以上是生活随笔為你收集整理的单元测试(二)基本使用争议篇的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Dapr牵手.NET学习笔记:跨物理机负
- 下一篇: BeetleX.WebFamily之Ma