<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Asp-Net-Core學習筆記:單元測試和集成測試

          共 5484字,需瀏覽 11分鐘

           ·

          2023-07-19 17:45

          1 前言

          我在使用 AspNetCore 的這段時間內(nèi),看了很多開源項目和博客,發(fā)現(xiàn)各種 .Net 體系的新技術(shù)很多人都有關(guān)注和使用,但卻很少有人關(guān)注測試。

          測試是軟件生命周期中的一個非常重要的階段,對于保證軟件的可靠性具有極其重要的意義。在應用程序的開發(fā)過程中,為了確保它的功能與預期一致,必須對其進行測試。這樣做不僅能夠確保功能正確執(zhí)行,同時能夠幫助開發(fā)人員盡早地發(fā)現(xiàn)并改正系統(tǒng)中所存在的缺陷(Bug),從而提高軟件的可靠性。測試應該覆蓋到軟件的所有功能,全面、細致的測試會在很大程度上節(jié)省軟件開發(fā)的成本;反之,不足的測試勢必會使軟件包含一些未發(fā)現(xiàn)的缺陷而投入運行,使用戶承擔軟件缺陷所造成的危險。

          從測試所涉及的層次上,分為單元測試、集成測試和系統(tǒng)測試。單元測試是指驗證代碼段(如方法或函數(shù))功能的測試,通常由開發(fā)人員編寫相應的測試方法,以驗證代碼執(zhí)行后與預期結(jié)果是否一致;集成測試用于驗證具有依賴關(guān)系的多個模塊或組件是否能夠正常工作;系統(tǒng)測試是對整個系統(tǒng)進行全面測試,以確認系統(tǒng)正常運行并符合需求。

          本文主要記錄一下單元測試和集成測試。

          PS:本文只介紹簡單的測試方法,拋磚引玉,更深入的使用可以參考官方文檔,其中寫得很清楚。

          2 .Net 中的測試

          .Net 的測試項目,主要有幾種模板

          • MSTest
          • NUnit
          • xUnit

          本文選擇 xUnit 作為測試項目模板。

          3 單元測試

          從測試所涉及的層次上,分為單元測試、集成測試和系統(tǒng)測試。單元測試是指驗證代碼段(如方法或函數(shù))功能的測試,通常由開發(fā)人員編寫相應的測試方法,以驗證代碼執(zhí)行后與預期結(jié)果是否一致;集成測試用于驗證具有依賴關(guān)系的多個模塊或組件是否能夠正常工作;系統(tǒng)測試是對整個系統(tǒng)進行全面測試,以確認系統(tǒng)正常運行并符合需求。

          • Arrange:為測試進行準備操作,如設(shè)置測試數(shù)據(jù)、變量和環(huán)境等。
          • Act:執(zhí)行要測試的方法,如調(diào)用要測試的函數(shù)和方法。
          • Assert:斷言測試結(jié)果,驗證被測試方法的輸出是否與預期的結(jié)果一致。

          最簡單的例子

          Controller 代碼

                
                [ApiController]
          public?class?DemoController?:?ControllerBase?{
          ??[HttpGet("[action]")]
          ??public?ApiResponse?Test()?{
          ????return?ApiResponse.Ok("version=2.0");
          ??}
          }

          單元測試代碼

                
                public?class?DemoTests?{
          ??private?readonly?DemoController?_demoController;

          ??public?DemoTests()?{
          ????_demoController?=?new?DemoController();
          ????_demoController.ControllerContext?=?new?ControllerContext?{
          ??????HttpContext?=?new?DefaultHttpContext()
          ????};
          ??}

          ??[Fact]
          ??public?void?Test_Test()?{
          ????var?resp?=?_demoController.Test();
          ????Assert.Equal("version=2.0",?resp.Message);
          ??}
          }

          帶參數(shù)的 controller

          實際開發(fā)中,Controller 會使用依賴注入,有很多參數(shù)

          比如這個 controller ,用到了 EFCore 的 DbContext

                
                public?class?StudentController?:?ControllerBase?{
          ??private?readonly?AppDbContext?_dbCtx;

          ??public?StudentController(AppDbContext?dbCtx)?{
          ????_dbCtx?=?dbCtx;
          ??}
          ??///?<summary>
          ??///?學生分數(shù)等級
          ??///?</summary>
          ??[HttpGet("[action]")]
          ??public?async?Task<List<StudentGrades>>?StudentScoreGrades()?{
          ????return?await?_dbCtx.StudentGrades.ToListAsync();
          ??}
          }

          這時候在單元測試里,就得用 mock 對象框架 來實現(xiàn)依賴模擬

          這里用的是 Moq 這個庫,可以直接 nuget 安裝

                
                public?class?StudentTests?{
          ??private?readonly?StudentController?_studentController;

          ??public?StudentTests()?{
          ????var?mockOptions?=?new?Mock<DbContextOptions<AppDbContext>>();
          ????var?mockDbContext?=?new?Mock<AppDbContext>(mockOptions.Object);
          ????_studentController?=?new?StudentController(mockDbContext.Object)?{
          ??????ControllerContext?=?new?ControllerContext?{
          ????????HttpContext?=?new?DefaultHttpContext()
          ??????}
          ????};
          ??}

          ??[Fact]
          ??public?async?Task?Test_StudentScoreGrades()?{
          ????var?resp?=?await?_studentController.StudentScoreGrades();
          ????Assert.True(resp.Count?>?0);
          ??}
          }

          PS:實際使用的時候,這個 mock 還是挺麻煩的,所以這些接口還是用后面的集成測試更好。

          4 集成測試

          集成測試能夠確保應用程序的組件正常工作,包括應用程序支持的基礎(chǔ)結(jié)構(gòu),如數(shù)據(jù)庫和文件系統(tǒng)等。ASP.NET Core提供了用于集成測試的組件,其中包含了用于測試的WebHost和內(nèi)存測試服務器TestServer。與單元測試不同,這里所有的依賴都是模擬出來的,在集成測試中,應使用與生產(chǎn)環(huán)境中一樣的真實組件,如數(shù)據(jù)庫和第三方庫等。

          簡單說,單元測試是把所有組件都模擬一遍,集成測試是在真實的系統(tǒng)上進行測試,比如 AspNetCore 開發(fā)的接口,集成測試直接使用 HTTP 請求,獲取接口數(shù)據(jù),然后檢查這些返回數(shù)據(jù)是否符合條件。

          開始前需要先安裝依賴

                
                dotnet?add?Microsoft.AspNetCore.Mvc.Testing

          公開被測試項目的 Program/Startup 類

          集成測試使用 WebApplicationFactory 來啟動 AspNetCore 應用

          所以需要在被測試的應用里做一點小修改,以便讓測試項目可以訪問到它的 Program

          本文使用的被測試項目是基于 .Net6 的,修改它的 Program.cs ,添加以下代碼

                
                public?partial?class?Program?{?}

          使其 Program 類變成共有,讓測試項目能夠訪問到。

          官網(wǎng)文檔上說還可以修改 .csproj ,添加配置

                
                <ItemGroup>
          ??<InternalsVisibleTo?Include="MyTestProject"?/>
          </ItemGroup>

          但我試了好像沒有效果,所以還是用第一種方法比較方便。

          PS:如果是 .Net6 之前的項目,就把 Startup 類改成 public

          例子

          以剛才的 Student 接口為例

          用 HTTP 請求這幾個接口,然后判斷返回的響應頭里是否符合條件。

                
                public?class?StudentTests?:?IClassFixture<WebApplicationFactory<Program>>?{
          ??private?readonly?WebApplicationFactory<Program>?_factory;

          ??public?StudentTests(WebApplicationFactory<Program>?factory)?{
          ????_factory?=?factory;
          ??}

          ??[Theory]
          ??[InlineData("/api/v2/Student/StudentScoreGrades")]
          ??[InlineData("/api/v2/Student/Height")]
          ??[InlineData("/api/v2/Student/Weight")]
          ??public?async?Task?Get_EndpointsReturnSuccessAndCorrectContentType(string?url)?{
          ????var?client?=?_factory.CreateClient();
          ????var?response?=?await?client.GetAsync(url);
          ????response.EnsureSuccessStatusCode();
          ????Assert.Equal("application/json;?charset=utf-8;?ver=2",?response.Content.Headers.ContentType?.ToString());
          ??}
          }

          更多示例

          本文只介紹了 WebApi 的集成測試,實際開發(fā)可能還會對 MVC、Blazor 等項目進行測試

          官方提供了一個實例項目: https://github.com/dotnet/AspNetCore.Docs.Samples/tree/main/test/integration-tests/IntegrationTestsSample

          里面有很多集成測試的例子,可以參考一下。

          5 運行測試

          第一次測試需要先 Build 測試項目

          本文使用的 IDE 是 Rider(VS 的話也是大同小異),其中提供了可視化的測試界面

          0ba0c7c9667ac9e926cf210e189e7412.webp

          之后寫完新的測試直接點擊旁邊的綠色三角形,就可以單獨運行這個新的測試。

          6 參考資料

          • https://learn.microsoft.com/zh-cn/aspnet/core/mvc/controllers/testing
          • https://learn.microsoft.com/zh-cn/aspnet/core/test/integration-tests


          瀏覽 37
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  五月丁香激情综合 | 78m成人视频中文音声 | 一本免费无码 | AV无码电影| 俺来也俺去也色www |