Criar testes com o .NET Aspire

Concluído

O teste é uma parte essencial do desenvolvimento de software de alta qualidade. O teste pode ajudar você a encontrar e corrigir bugs, aprimorar o desempenho e garantir que seu código atenda aos requisitos e às expectativas dos usuários. O teste também pode ajudar você a automatizar o processo de implantação e evitar regressões no futuro. O .NET Aspire fornece ferramentas e bibliotecas para simplificar o desenvolvimento, o teste e a implantação de aplicativos distribuídos.

Nesta unidade, você aprenderá a testar projetos do .NET Aspire usando o xUnit, uma estrutura de teste popular para .NET. Você aprenderá a criar diferentes tipos de testes, como testes de integração e testes funcionais, e como executá-los usando a CLI do .NET Aspire ou o Visual Studio.

Criar um projeto de teste

A maneira mais fácil de criar um projeto de teste do .NET Aspire é usar o modelo de projeto de teste. Você pode usar o comando dotnet new para criar um projeto de biblioteca de classes padrão e, em seguida, adicionar as referências às bibliotecas de teste do .NET Aspire e aos pacotes xUnit.

dotnet new aspire-xunit

Explorar o projeto de teste

O projeto de teste de exemplo a seguir foi criado como parte do modelo de aplicativo do .NET Aspire Starter. Se você não estiver familiarizado com isso, confira o Início Rápido: Crie seu primeiro projeto do .NET Aspire. O projeto de teste do .NET Aspire usa uma dependência de referência de projeto no host do aplicativo de destino. Considere o projeto de modelo:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>net8.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
    <IsPackable>false</IsPackable>
    <IsTestProject>true</IsTestProject>
  </PropertyGroup>


  <ItemGroup>
    <PackageReference Include="Aspire.Hosting.Testing" Version="8.1.0" />
    <PackageReference Include="coverlet.collector" Version="6.0.2" />
    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.11.0" />
    <PackageReference Include="xunit" Version="2.9.0" />
    <PackageReference Include="xunit.runner.visualstudio" Version="2.8.2" />
  </ItemGroup>

  <ItemGroup>
    <ProjectReference Include="..\AspireApp.AppHost\AspireApp.AppHost.csproj" />
  </ItemGroup>

  <ItemGroup>
    <Using Include="System.Net" />
    <Using Include="Microsoft.Extensions.DependencyInjection" />
    <Using Include="Aspire.Hosting.ApplicationModel" />
    <Using Include="Aspire.Hosting.Testing" />
    <Using Include="Xunit" />
  </ItemGroup>

</Project>

O arquivo de projeto anterior é bastante padrão. Há um PackageReference para o pacote NuGet Aspire.Hosting.Testing, que inclui os tipos necessários para escrever testes para projetos do .NET Aspire.

O projeto de teste de modelo inclui uma classe WebTests com apenas um teste. O teste verifica o seguinte cenário:

  • O host do aplicativo é criado e iniciado com êxito.
  • O recurso webfrontend está disponível e em execução.
  • Uma solicitação HTTP pode ser feita ao recurso webfrontend e retorna uma resposta bem-sucedida (HTTP 200 OK).

Considere a seguinte classe de teste:

namespace AspireApp.Tests;

public class WebTests
{
    [Fact]
    public async Task GetWebResourceRootReturnsOkStatusCode()
    {
        // Arrange
        var appHost = await DistributedApplicationTestingBuilder
            .CreateAsync<Projects.AspireApp_AppHost>();

        appHost.Services.ConfigureHttpClientDefaults(clientBuilder =>
        {
            clientBuilder.AddStandardResilienceHandler();
        });

        await using var app = await appHost.BuildAsync();

        var resourceNotificationService = app.Services
            .GetRequiredService<ResourceNotificationService>();
        
        await app.StartAsync();

        // Act
        var httpClient = app.CreateHttpClient("webfrontend");

        await resourceNotificationService.WaitForResourceAsync(
                "webfrontend",
                KnownResourceStates.Running
            )
            .WaitAsync(TimeSpan.FromSeconds(30));
        
        var response = await httpClient.GetAsync("/");

        // Assert
        Assert.Equal(HttpStatusCode.OK, response.StatusCode);
    }
}

O código anterior:

  • Depende de DistributedApplicationTestingBuilder para criar o host de aplicativo de maneira assíncrona.
  • O appHost faz com que o respectivo método BuildAsync seja invocado, o qual retorna a instância de DistributedApplication como o app.
    • O app faz com que o provedor de serviços dele obtenha a instância de ResourceNotificationService.
    • O app é iniciado de maneira assíncrona.
  • Um HttpClient é criado para o recurso webfrontend chamando app.CreateHttpClient.
  • O recurso resourceNotificationService é usado para aguardar que o recurso webfrontend esteja disponível e em execução.
  • Uma solicitação HTTP GET simples é feita na raiz do recurso webfrontend.
  • O teste afirma que o código de status de resposta é OK.