Tworzenie testów za pomocą platformy .NET Aspire

Ukończone

Testowanie jest istotną częścią tworzenia oprogramowania wysokiej jakości. Testowanie może pomóc w znalezieniu i naprawieniu usterek, poprawie wydajności i upewnieniu się, że kod spełnia wymagania i oczekiwania użytkowników. Testowanie może również pomóc zautomatyzować proces wdrażania i zapobiec regresjom w przyszłości. Platforma .NET Aspire udostępnia narzędzia i biblioteki ułatwiające opracowywanie, testowanie i wdrażanie aplikacji rozproszonych.

W tej lekcji dowiesz się, jak testować projekty platformy .NET Aspire przy użyciu narzędzia xUnit, popularnej platformy testowania dla platformy .NET. Dowiesz się, jak tworzyć różne typy testów, takie jak testy integracji i testy funkcjonalne, oraz jak je uruchamiać przy użyciu interfejsu wiersza polecenia platformy .NET Aspire lub programu Visual Studio.

Tworzenie projektu testowego

Najprostszym sposobem utworzenia projektu testowego platformy .NET Aspire jest użycie szablonu projektu testowego. Możesz użyć dotnet new polecenia , aby utworzyć standardowy projekt biblioteki klas, a następnie dodać odwołania do bibliotek testowych platformy .NET Aspire i pakietów xUnit.

dotnet new aspire-xunit

Eksplorowanie projektu testowego

Poniższy przykładowy projekt testowy został utworzony jako część szablonu aplikacji startowej .NET Aspire. Jeśli nie znasz go, zobacz Szybki start: tworzenie pierwszego projektu .NET Aspire. Projekt testowy platformy .NET Aspire przyjmuje zależność referencyjną projektu od hosta aplikacji docelowej. Rozważ projekt szablonu:

<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>

Powyższy plik projektu jest dość standardowy. Pakiet NuGet Aspire.Hosting.Testing zawiera PackageReference wymagane typy do pisania testów dla projektów .NET Aspire.

Projekt testowy szablonu zawiera klasę WebTests z jednym testem. Test sprawdza następujący scenariusz:

  • Host aplikacji został pomyślnie utworzony i uruchomiony.
  • Zasób webfrontend jest dostępny i uruchomiony.
  • Żądanie HTTP można wysłać do webfrontend zasobu i zwrócić pomyślną odpowiedź (HTTP 200 OK).

Rozważmy następującą klasę testowa:

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);
    }
}

Powyższy kod ma następujące działanie:

  • Zależy od DistributedApplicationTestingBuilder asynchronicznego tworzenia hosta aplikacji.
    • Jest appHost to wystąpienie IDistributedApplicationTestingBuilder , które reprezentuje hosta aplikacji.
    • Wystąpienie appHost ma swoją kolekcję usług skonfigurowaną przy użyciu standardowej procedury obsługi odporności HTTP. Aby uzyskać więcej informacji, zobacz Tworzenie odpornych aplikacji HTTP: kluczowe wzorce programistyczne.
  • Element appHost ma wywołaną BuildAsync metodę, która zwraca DistributedApplication wystąpienie jako app.
  • Element HttpClient jest tworzony dla webfrontend zasobu przez wywołanie metody app.CreateHttpClient.
  • Element resourceNotificationService służy do oczekiwania, aż webfrontend zasób będzie dostępny i uruchomiony.
  • Proste żądanie HTTP GET jest wykonywane do katalogu głównego webfrontend zasobu.
  • Test potwierdza, że kod stanu odpowiedzi to OK.