[.NET Blog] .NET Aspire 测试入门
https://devblogs.microsoft.com/dotnet/getting-started-with-testing-and-dotnet-aspire/
自动化测试是软件开发的重要一环。它可以帮助我们尽早确认软件中的缺陷和防止回归问题。在本文中,我们将探讨如何在 .NET Aspire 中开始测试,支持我们进行跨分布式应用的测试场景。
测试分布式应用
分布式应用存在本质上的复杂性。你需要确保各种组件,例如数据库、缓存等等可用并且工作在正确的状态。然后,你的应用可能存在众多的服务需要一起进行测试。.NET Aspire 是非常棒的工具来帮助我们定义应用程序的环境,将众多的服务和资源连接在一起,进而比较容易地启动我们的环境。
对于端到端的测试也是这样,或者对于集成测试,我们需要确保数据库在期望的测试状态,避免其他的测试影响我们的测试,并且确保应用运行在正确的配置之下,这也是 .NET Aspire 可以提供帮助的地方。
谢天谢地,我们拥有了 .NET Aspire 的 Aspire.Hosting.Testing NuGet Package,它可以在这些方面帮助我们,让我们看一下我们可以如何使用它来编写测试用例。
入门
在开始的时候,我们将创建一个新的 .NET Aspire Starter App 项目,这将会创建一个新的使用了 AppHost 的 .NET Application,以及 Service Defaults, 和一个 API backend 和 一个 Blazor Web 前端项目。
首先确保你已经安装了 .NET Aspire workload
dotnet workload update
dotnet workload install aspire
然后,使用 aspire-starter 模板来创建新的项目。
dotnet new aspire-starter --name AspireWithTesting
然后,我们需要添加测试项目了,我们可以从 3 个测试框架中选择你希望的那个:
- MSTest
- xUnit
- Nunit
例如,我们这里使用 MSTest。这可以通过使用 aspire-mstest 模板来完成。
dotnet new aspire-mstest --name AspireWithTesting.Tests
dotnet sln add AspireWithTesting.Tests
注意:在使用
aspire-starter模板创建项目的时候,通过使用参数--test-framework MSTest,你可以直接在新创建的项目中包含该测试项目。
在模板中已经引用了 Aspire-Hosting.Testing NuGet 包,以及选择的测试框架,在这里是 MSTest。所以,最后需要做的事情就是将测试项目添加到 AppHost 项目中。
dotnet add AspireWithTesting.Tests reference AspireWithTesting.AppHost
编写测试
你会发现这里已经提供了一个初始的测试文件,在上面描述中创建的测试项目中的 IntegrationTest1.cs。它提供了一个测试的示例,不过,我们还是从头编写一个,以便我们理解需要做的内容。创建一个新的名为 FrontEndTests.cs 的文件并试下下面的内容:
namespace AspireWithTesting.Tests;
[TestClass]
public class FrontEndTests
{
[TestMethod]
public async Task CanGetIndexPage()
{
var appHost =
await DistributedApplicationTestingBuilder
.CreateAsync<Projects.AspireWithTesting_AppHost>();
appHost.Services.ConfigureHttpClientDefaults(clientBuilder =>
{
clientBuilder.AddStandardResilienceHandler();
});
await using var app = await appHost.BuildAsync();
await app.StartAsync();
var resourceNotificationService =
app.Services.GetRequiredService<ResourceNotificationService>();
await resourceNotificationService
.WaitForResourceAsync("webfrontend", KnownResourceStates.Running)
.WaitAsync(TimeSpan.FromSeconds(30));
var httpClient = app.CreateHttpClient("webfrontend");
var response = await httpClient.GetAsync("/");
Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
}
}
ResourceNotificationService 支持发布和订阅资源状态更改的服务。
好极了,测试已经写好了,让我们执行一下它。
dotnet test
如果所有的组件都在计划中执行,我们将应该看到如下的输出:
Test summary: total: 1, failed: 0, succeeded: 1, skipped: 0, duration: 0.9s
理解测试
让我分解上面的代码,理解在测试中发生了什么。
var appHost =
await DistributedApplicationTestingBuilder
.CreateAsync<Projects.AspireWithTesting_AppHost>();
appHost.Services.ConfigureHttpClientDefaults(clientBuilder =>
{
clientBuilder.AddStandardResilienceHandler();
});
await using var app = await appHost.BuildAsync();
await app.StartAsync();
测试的第一部分是利用在 AppHost 项目中定义的所有资源、服务和它们的关系,然后启动它们,如同在 AppHost 项目中执行 dotnet run 一样。但是在测试项目中,我们可以控制一些额外的方面。例如,我们可以注入 StandardResilienceHandler 到 HttpClient 中,这样测试中可以可以用来与 AppHost 中的服务交互。在 AppHost 配置之后,我们构建整个应用,准备开始执行测试。
var resourceNotificationService =
app.Services.GetRequiredService<ResourceNotificationService>();
await resourceNotificationService
.WaitForResourceAsync("webfrontend", KnownResourceStates.Running)
.WaitAsync(TimeSpan.FromSeconds(30));
因为 AppHost 将要启动多个不同的资源和服务,我们需要在基于它们执行我们的测试之前,确保它们可用。在这之后,如果 Web 应用没有正常启动,而我们试图访问它,我们就会得到一个错误。ResourceNotificationService 是用来帮助我们等待某个服务进入特定状态的服务。在我们的这个示例中,我们将等待 Webfrontend (这是配置在 AppHost 中的名称) 进入 Running 状态,我们使用 30s 的时间来等待。这个模式将需要对任何我们需要交互的服务使用,不管是直接还是间接。
var httpClient = app.CreateHttpClient("webfrontend");
var response = await httpClient.GetAsync("/");
Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
最后,我们可以从启动之后的应用中申请一个 HttpClient 的实例,提供希望访问的服务名称。这里将使用与以后的应用程序实际场景一样的服务发现机制,所以,我们不用担心服务的 URL 或者端口号。我们可以向服务发出请求,在我们的这个示例中,我们访问了 Web 前端的根目录 /,并检查我们是否得到一个 200 OK 的响应。来确认服务正确执行并如期望进行响应。
测试 API
测试 API 的方式非常类似于测试前端服务的方式,因为它返回的是数据,我们可以更进一步,可以根据返回的数据进行断言。
using System.Net.Http.Json;
namespace AspireWithTesting.Tests;
[TestClass]
public class ApiTests
{
[TestMethod]
public async Task CanGetWeatherForecast()
{
var appHost =
await DistributedApplicationTestingBuilder.CreateAsync<Projects.AspireWithTesting_AppHost>();
appHost.Services.ConfigureHttpClientDefaults(clientBuilder =>
{
clientBuilder.AddStandardResilienceHandler();
});
await using var app = await appHost.BuildAsync();
await app.StartAsync();
var resourceNotificationService =
app.Services.GetRequiredService<ResourceNotificationService>();
await resourceNotificationService
.WaitForResourceAsync("apiservice", KnownResourceStates.Running)
.WaitAsync(TimeSpan.FromSeconds(30));
var httpClient = app.CreateHttpClient("apiservice");
var response = await httpClient.GetAsync("/weatherforecast");
Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
var forecasts = await response.Content.ReadFromJsonAsync<IEnumerable<WeatherForecast>>();
Assert.IsNotNull(forecasts);
Assert.AreEqual(5, forecasts.Count());
}
record WeatherForecast(DateOnly Date, int TemperatureC, string? Summary);
}
注意:由于这里涉及的
record类型的WeatherForecast是在 API 项目中私有定义的,我们我们需要在测试项目中重新定义它,以便反序列化收到的 JSON 数据。
一旦我们断言 API 端点返回了期望的 200 OK 响应,我们可以进而反序列化收到的 JSON 响应为 WeatherForecast 对象的集合,并基于这些数据进一步断言。在我们的示例中,我们的 API 返回的是随机生成的数据,所以我们仅仅断言返回的 record 的数量,不过,如果我们的数据是来自于数据库中,那么,断言就可以根据期望的数据进行。
总结
在本文中,我们介绍了如何开始在 .NET Aspire 中进行测试。它使得我们可以处理分布式应用的测试场景。我们也看到了如何针对前端应用和 API 服务开发测试用例,确保它们运行并如期望进行响应。
Reference:
[.NET Blog] .NET Aspire 测试入门的更多相关文章
- Android渗透测试Android渗透测试入门教程大学霸
Android渗透测试Android渗透测试入门教程大学霸 第1章 Android渗透测试 Android是一种基于Linux的自由及开放源代码的操作系统,主要用于移动设备,如智能手机.平板等.目前 ...
- IOS 客户端测试入门.pdf
IOS 客户端测试入门 http://www.open-open.com/doc/view/42d1257bf67946f595e843bfdbdfeabf
- Python 3.6.3 官网 下载 安装 测试 入门教程 (windows)
1. 官网下载 Python 3.6.3 访问 Python 官网 https://www.python.org/ 点击 Downloads => Python 3.6.3 下载 Python ...
- 转载:JMeter压力测试入门教程[图文]
JMeter压力测试入门教程[图文] Apache JMeter是Apache组织开发的基于Java的压力测试工具.用于对软件做压力测试,它最初被设计用于Web应用测试但后来扩展到其他测试领域. 它可 ...
- Jmeter压力测试入门操作
Jmeter压力测试入门 1. 前言 Jmeter 是Apache组织开发的基于Java的压力测试工具,开源并且支持多个操作系统,是一款很好的HTTP测试工具.本篇文章主要的目的是帮助没有接触过J ...
- 渗透测试入门DVWA 教程1:环境搭建
首先欢迎新萌入坑.哈哈.你可能抱着好奇心或者疑问.DVWA 是个啥? DVWA是一款渗透测试的演练系统,在圈子里是很出名的.如果你需要入门,并且找不到合适的靶机,那我就推荐你用DVWA. 我们通常将演 ...
- 安全性测试入门:DVWA系列研究(一):Brute Force暴力破解攻击和防御
写在篇头: 随着国内的互联网产业日臻成熟,软件质量的要求越来越高,对测试团队和测试工程师提出了种种新的挑战. 传统的行业现象是90%的测试工程师被堆积在基本的功能.系统.黑盒测试,但是随着软件测试整体 ...
- 新萌渗透测试入门DVWA 教程1:环境搭建
首先欢迎新萌入坑.哈哈.你可能抱着好奇心或者疑问.DVWA 是个啥? DVWA是一款渗透测试的演练系统,在圈子里是很出名的.如果你需要入门,并且找不到合适的靶机,那我就推荐你用DVWA. 我们通常将演 ...
- Android Monkey测试入门
第一步:搭建环境:主要是安装和搭建java和sdk环境,说白了,对我们安卓开发来说,只要搭建好了Android开发环境,Monkey测试环境基本就是OK的了.可以参考:http://www.cnblo ...
- [大数据测试]ETL测试或数据仓库测试入门
转载自: http://blog.csdn.net/zhusongziye/article/details/78633934 概述 在我们学习ETL测试之前,先了解下business intellig ...
随机推荐
- 利用 Page Visibility API 优化网页性能与用户体验
在现代 Web 开发中,用户可能会频繁切换标签页,或让网页处于后台运行.为了避免不必要的资源浪费并提升用户体验,合理利用 Page Visibility API 可以在页面不可见时暂停或减少资源的消耗 ...
- 《Vue.js 设计与实现》读书笔记 - 第 4 章、响应系统的作用与实现
第 4 章.响应系统的作用与实现 4.1 响应式数据与副作用 副作用函数就是会对外部造成影响的函数,比如修改了全局变量. 响应式:修改了某个值的时候,某个会读取该值的副作用函数能够自动重新执行. 4. ...
- BPF BTF 详解
1. 介绍 BTF(BPF Type Format)是内嵌在BPF(Berkeley Packet Filter)程序中的数据结构描述信息.BPF原本是用于数据包过滤的编程语言,但随着eBPF(ext ...
- vue前端使用nexus配置npm私有仓库
当我们运行前端项目的时候,常常在解决依赖的时候会加上一个参数npm install --registry=https://registry.npm.taobao.org将源指定为淘宝的源,以期让速度加 ...
- 新建 Blazor 项目 WebAssembly
- IHostedService(BackgroundService)的启动和停止顺序
一句话总结: 按照Add顺序启动, 先启动, 后停止. Host 源代码 public async Task StartAsync(CancellationToken cancellationToke ...
- KubeSphere 社区双周报|2024.02.01-02.29
KubeSphere 社区双周报主要整理展示新增的贡献者名单和证书.新增的讲师证书以及两周内提交过 commit 的贡献者,并对近期重要的 PR 进行解析,同时还包含了线上/线下活动和布道推广等一系列 ...
- ajax下载二进制文件(导出Excel)
var url = 'http://127.0.0.1'; var xhr = new XMLHttpRequest(); xhr.open('GET', url, true); // 也可以使用PO ...
- HTTP常用返回结果状态码
摘编自<图解HTTP> HTTP状态码负责表示客户端 HTTP请求的返回结果.标记服务器端的处理是否正常.通知出现的错误等工作.状态码的职责是当客户端向服务器端发送请求时,描述返回的请求 ...
- RMI,SOA,微服务
什么是SOA SOA(Service-Oriented Architecture),中文全称:面向服务的架构. SOA提倡将不同应用程序的业务功能封装成"服务"并宿主起来,通常以接 ...