前言
在進行 Asp.Net Core 應用程序開發過程中,通常的做法是先把業務代碼開發完成,然后建立單元測試,最后進入本地系統集成測試;在這個過程中,程序員的大部分時間幾乎都花費在開發、運行、調試上,而且一再的重復這個過程,我稱這個過程為“程序員開發螺旋”,並且在這個步驟中,重復率最高且沒有創造力的工作就是啟動、測試,作為程序員,努力提高生產力我們追求的目標,我們的工作就是盡量消滅重復勞動,解放生產力,提高產出效率;下面就通過一個簡單的例子來演示,如何通過文件監視進行快速開發。
- 本示例將會使用兩個項目用作演示,如下圖
1. 建立業務項目 UserCenterDemo
1.1 在 UserCenterDemo.HomeController 里面編寫一個簡單的業務方法
[Route("api/[controller]")]
[ApiController]
public class HomeController : ControllerBase
{
[HttpGet("{id}")]
public IActionResult Get(int id)
{
int code = 0;
string userName = string.Empty;
switch (id)
{
case 100:
userName = "Ron.liang";
break;
default:
userName = "Guest";
code = 403;
break;
}
return new JsonResult(new { code, userName });
}
}
該業務方法非常簡單,僅根據傳入的 id 值進行判斷,如果不是 100 則返回 code=403
2. 建立 xUnit 單元測試項目 UserCenterDemoTest
2.1 引用項目 UserCenterDemo 和引用 NuGet 包
Microsoft.AspNetCore.App
Microsoft.AspNetCore.TestHost
UserCenterDemo 使用了主機集成測試方式,對主機集成測試不了解到同學,可以查看我上一篇博客: Asp.Net Core 輕松學-利用xUnit進行主機級別的網絡集成測試.
2.2 編寫測試用例 UserCenterDemoTest.HomeControllerTest.cs
public class HomeControllerTest
{
public static TestServer serverHost;
public static HttpClient client;
public HomeControllerTest()
{
if (serverHost == null)
{
serverHost = new TestServer(new WebHostBuilder().UseStartup<UserCenterDemo.Startup>());
client = serverHost.CreateClient();
}
}
class TestResult
{
public int Code { get; set; }
public string UserName { get; set; }
}
[Fact]
public async void GetUserNameTest()
{
var data = await client.GetAsync("/api/home/100");
var result = await data.Content.ReadAsStringAsync();
var obj = JsonConvert.DeserializeObject<TestResult>(result);
Assert.Equal(0, obj.Code);
}
[Fact]
public async void GetGuestTest()
{
var data = await client.GetAsync("/api/home/0");
var result = await data.Content.ReadAsStringAsync();
var obj = JsonConvert.DeserializeObject<TestResult>(result);
Console.WriteLine(result);
Assert.Equal(403, obj.Code);
}
}
該測試包含兩個測試方法,分別是獲取 id=100 的用戶和 id=0 的 Guest 用戶
3. 使用 dotnet watch 進行監視測試
按照以往的開發習慣,我們現在應該做的事情可能有兩個,一是啟動項目使用瀏覽器進行訪問業務接口 Get ,二是運行單元測試,不管怎么樣,這兩個動作都將消耗我們大量的時間
現在,有一種全新的選擇,我們可以通過使用 dotnet watch test 對項目文件進行監視變動,自動運行單元測試,並將測試結果輸出到控制台
3.1 打開 cmd.exe 程序,切換到測試項目目錄 UserCenterDemoTest,輸入 dotnet watch test,等待運行
上圖表示,當我們輸入命令 dotnet watch test 后,監視程序正在啟動,並在啟動完成后立即執行了一次單元測試,紅色方框部分表示有 2 個測試用例已通過,然后程序並沒有退出,而是在最后輸出了一個提示,正在等待文件變動以重啟 dotnet 應用程序
3.2 接下來我們修改測試用例 GetGuestTest 的斷言結果 code=0,看看發生了什么
可以看到,在修改完成保存文件的瞬間,程序立即重啟生成,然后執行測試,測試結果斷言不通過
那么問題來了,上面只是監視了測試項目,如果我們修改了 UserCenterDemo.Controllers ,能夠自動監視嗎,答案是肯定的
3.3 現在修改 UserCenterDemo.Controllers ,修改獲取 Guest 的 code=0,返回成功
[Route("api/[controller]")]
[ApiController]
public class HomeController : ControllerBase
{
[HttpGet("{id}")]
public IActionResult Get(int id)
{
int code = 0;
string userName = string.Empty;
switch (id)
{
case 100:
userName = "Ron.liang";
break;
default:
userName = "Guest";
code = 403;
break;
}
return new JsonResult(new { code, userName });
}
}
- 輸出結果,已自動監視執行
為什么會這樣呢,因為我們的測試項目引用了業務項目 UserCenterDemo
所以可以監視到,查看 UserCenterDemoTest.csproj 文件,起作用的是以下代碼
<ItemGroup>
<ProjectReference Include="..\UserCenterDemo\UserCenterDemo.csproj" />
</ItemGroup>
5. 擴展使用
5.1 如果你覺得總是不停的輸出各種信息讓你覺得很不友好,那么你可以排除監視,比如移除對 UserCenterDemo.csproj 的監視,只需要增加配置 Watch="false" 即可
<ItemGroup>
<ProjectReference Include="..\UserCenterDemo\UserCenterDemo.csproj" Watch="false"/>
</ItemGroup>
5.2 獨立監視
當項目比較大的時候,我們可能需要對監視項目進行管理,這個時候再逐一的對每個項目進行監視設置就變得非常的麻煩,然后我們就可以建立一個單獨的文件夾,創建一個 watch.csproj 文件,填如下面的內容
<Project>
<ItemGroup>
<TestProjects Include="..\**\*.csproj" />
<Watch Include="..\**\*.cs" />
</ItemGroup>
<Target Name="WatchManage">
<MSBuild Targets="VSTest" Projects="@(TestProjects)" />
</Target>
<Import Project="$(MSBuildExtensionsPath)\Microsoft.Common.targets" />
</Project>
5.3 注意路徑,因為本示例的目錄結構是這樣
所以文件中的監視節點我必須加入 ..\ 回退到上一級,上面的代碼表示,監視上一級目錄下的 .csproj/.cs 文件變動,並為本次監視管理命名為:WatchManage
5.4 現在進入目錄 watch 輸入命令 dotnet watch msbuild /t:WatchManager
可以看到,已經成功對兩個項目進行變動監視
結束語
- 通過本示例,我們了解到如何在項目開發過程中減少重復勞動,提高生產力的方法
- 學習了 dotnet watch test 的使用方法
- 掌握了在應對項目繁多的時候,建立獨立文件監視管理器的方法
示例代碼下載
https://github.com/lianggx/EasyAspNetCoreDemo/tree/master/UserCenterDemo