Megosztás a következőn keresztül:


Írd meg az első .NET.NET Aspire tesztedet.

Ebből a cikkből megtudhatja, hogyan hozhat létre tesztprojektet, írhat teszteket, és futtathatja őket a .NET.NET Aspire-megoldásokhoz. A cikkben szereplő tesztek nem egységtesztek, hanem funkcionális vagy integrációs tesztek. .NET .NET Aspire számos különböző tesztelési projektsablont, amelyekkel tesztelheti .NET.NET Aspire erőforrásfüggőségeit és kommunikációját. A tesztelési projektsablonok az MSTest, az NUnit és az xUnit tesztelési keretrendszerekhez érhetők el, és tartalmaznak egy mintatesztet, amelyet kiindulópontként használhat a tesztekhez.

A .NET.NET Aspire tesztprojektsablonok a 📦Aspire.Hosting.Testing NuGet-csomagra támaszkodnak. Ez a csomag hozzáférést biztosít a DistributedApplicationTestingBuilder osztályhoz, amely használható tesztgazdagép létrehozására az elosztott alkalmazáshoz. Az elosztott alkalmazástesztelő a DistributedApplication osztályra támaszkodik a alkalmazásgazdalétrehozásához és elindításához.

Tesztprojekt létrehozása

A tesztelési projekt .NET.NET Aspire létrehozásának legegyszerűbb módja a tesztelési projektsablon használata. Ha új .NET.NET Aspire projektet indít, és tesztprojekteket szeretne belefoglalni, a Visual Studio eszközkészlet támogatja ezt a lehetőséget. Ha tesztprojektet ad hozzá egy meglévő .NET.NET Aspire projekthez, a dotnet new paranccsal létrehozhat egy tesztprojektet:

dotnet new aspire-xunit
dotnet new aspire-mstest
dotnet new aspire-nunit

További információért lásd a .NET parancssori felület dotnet new parancsdokumentációját.

A tesztprojekt megismerése

A következő példatesztelési projekt a .NET.NET Aspire Starter Application sablon részeként lett létrehozva. Ha nem ismeri ezt, tekintse meg a gyorsindítót: az első .NET.NET Aspire projektelkészítése. A .NET.NET Aspire tesztprojekt a célalkalmazás-gazdagépen egy projekthivatkozás-függőséget vesz igénybe. Fontolja meg a sablonprojektet:

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

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


  <ItemGroup>
    <PackageReference Include="Aspire.Hosting.Testing" Version="9.0.0" />
    <PackageReference Include="coverlet.collector" Version="6.0.4" />
    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
    <PackageReference Include="xunit" Version="2.9.3" />
    <PackageReference Include="xunit.runner.visualstudio" Version="3.0.1" />
  </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>
<Project Sdk="Microsoft.NET.Sdk">

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

  <PropertyGroup>
    <EnableMSTestRunner>true</EnableMSTestRunner>
    <OutputType>Exe</OutputType>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Aspire.Hosting.Testing" Version="9.0.0" />
    <PackageReference Include="MSTest" Version="3.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="Microsoft.VisualStudio.TestTools.UnitTesting" />
  </ItemGroup>

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

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


  <ItemGroup>
    <PackageReference Include="Aspire.Hosting.Testing" Version="9.0.0" />
    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
    <PackageReference Include="NUnit" Version="4.3.2" />
    <PackageReference Include="NUnit.Analyzers" Version="4.6.0" />
    <PackageReference Include="NUnit3TestAdapter" Version="4.6.0" />
  </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="NUnit.Framework" />
  </ItemGroup>

</Project>

Az előző projektfájl meglehetősen szabványos. Van egy PackageReference a 📦Aspire.Hosting.Testing NuGet-csomag, amely tartalmazza a tesztek írásához szükséges típusokat .NET.NET Aspire projektekhez.

A sablontesztelési projekt egyetlen teszttel rendelkező IntegrationTest1 osztályt tartalmaz. A teszt a következő forgatókönyvet ellenőrzi:

  • Az alkalmazás gazdagépének létrehozása és elindítása sikeresen megtörtént.
  • Az webfrontend erőforrás elérhető és fut.
  • HTTP-kérést lehet küldeni az webfrontend erőforrásnak, és sikeres választ ad vissza (HTTP 200 OK).

Vegye figyelembe a következő tesztosztályt:

namespace AspireApp.Tests;

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

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

        // To output logs to the xUnit.net ITestOutputHelper, 
        // consider adding a package from https://www.nuget.org/packages?q=xunit+logging

        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);
    }
}
namespace AspireApp.Tests;

[TestClass]
public class IntegrationTest1
{
    [TestMethod]
    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.AreEqual(HttpStatusCode.OK, response.StatusCode);
    }
}
namespace AspireApp.Tests;

public class IntegrationTest1
{
    [Test]
    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.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
    }
}

Az előző kód:

Erőforrás-környezeti változók tesztelése

Az erőforrások és azok kifejezett függőségeinek a .NET.NET Aspire megoldásban való további teszteléséhez állíthatja, hogy a környezeti változók megfelelően vannak injektálva. Az alábbi példa bemutatja, hogyan tesztelhetjük az webfrontend erőforrás HTTPS környezeti változóját, amely az apiservice erőforrásra oldódik fel:

using Aspire.Hosting;

namespace AspireApp.Tests;

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

        var frontend = (IResourceWithEnvironment)appHost.Resources
            .Single(static r => r.Name == "webfrontend");

        // Act
        var envVars = await frontend.GetEnvironmentVariableValuesAsync(
            DistributedApplicationOperation.Publish);

        // Assert
        Assert.Contains(envVars, static (kvp) =>
        {
            var (key, value) = kvp;

            return key is "services__apiservice__https__0"
                && value is "{apiservice.bindings.https.url}";
        });
    }
}
using Aspire.Hosting;

namespace AspireApp.Tests;

[TestClass]
public class EnvVarTests
{
    [TestMethod]
    public async Task WebResourceEnvVarsResolveToApiService()
    {
        // Arrange
        var appHost = await DistributedApplicationTestingBuilder
            .CreateAsync<Projects.AspireApp_AppHost>();

        var frontend = (IResourceWithEnvironment)appHost.Resources
            .Single(static r => r.Name == "webfrontend");

        // Act
        var envVars = await frontend.GetEnvironmentVariableValuesAsync(
            DistributedApplicationOperation.Publish);

        // Assert
        CollectionAssert.Contains(envVars,
            new KeyValuePair<string, string>(
                key: "services__apiservice__https__0",
                value: "{apiservice.bindings.https.url}"));
    }
}
using Aspire.Hosting;

namespace AspireApp.Tests;

public class EnvVarTests
{
    [Test]
    public async Task WebResourceEnvVarsResolveToApiService()
    {
        // Arrange
        var appHost = await DistributedApplicationTestingBuilder
            .CreateAsync<Projects.AspireApp_AppHost>();

        var frontend = (IResourceWithEnvironment)appHost.Resources
            .Single(static r => r.Name == "webfrontend");

        // Act
        var envVars = await frontend.GetEnvironmentVariableValuesAsync(
            DistributedApplicationOperation.Publish);

        // Assert
        Assert.That(envVars, Does.Contain(
            new KeyValuePair<string, string>(
                key: "services__apiservice__https__0",
                value: "{apiservice.bindings.https.url}")));
    }
}

Az előző kód:

Összefoglalás

A .NET Aspire tesztelési projektsablon megkönnyíti a tesztprojektek létrehozását .NET Aspire megoldásokhoz. A sablonprojekt tartalmaz egy mintatesztet, amelyet kiindulópontként használhat a tesztekhez. A DistributedApplicationTestingBuilder egy ismerős mintát követ, mint a WebApplicationFactory<TEntryPoint> a ASP.NET Core-ben. Lehetővé teszi egy tesztgazda létrehozását az elosztott alkalmazáshoz, és teszteket futtathat rajta.

Végül, amikor a DistributedApplicationTestingBuilder-t használják, alapértelmezés szerint az összes erőforrásnaplót átirányítják a DistributedApplication-re. Az erőforrásnaplók átirányítása olyan forgatókönyveket tesz lehetővé, amelyekben az erőforrás helyes naplózását szeretné érvényesíteni.

Lásd még: