Skriv ditt första .NET.NET Aspire test
I den här artikeln får du lära dig hur du skapar ett testprojekt, skriver tester och kör dem för dina .NET.NET Aspire lösningar. Testerna i den här artikeln är inte enhetstester, utan snarare funktions- eller integreringstester. .NET .NET Aspire innehåller flera varianter av projektmallar som du kan använda för att testa dina resursberoenden .NET.NET Aspire—och deras kommunikation. Testprojektmallarna är tillgängliga för MSTest-, NUnit- och xUnit-testramverk och innehåller ett exempeltest som du kan använda som utgångspunkt för dina tester.
De .NET.NET Aspire testprojektmallarna förlitar sig på 📦Aspire. Hosting.Testing NuGet-paket. Det här paketet exponerar klassen DistributedApplicationTestingBuilder, som används för att skapa en testvärd för ditt distribuerade program. Den distribuerade applikationsbyggaren för testning förlitar sig på DistributedApplication-klassen för att skapa och starta värdprogram.
Skapa ett testprojekt
Det enklaste sättet att skapa ett .NET.NET Aspire testprojekt är att använda testprojektmallen. Om du startar ett nytt .NET.NET Aspire projekt och vill inkludera testprojekt stöder Visual Studio-verktyget det alternativet. Om du lägger till ett testprojekt i ett befintligt .NET.NET Aspire projekt kan du använda kommandot dotnet new
för att skapa ett testprojekt:
dotnet new aspire-xunit
dotnet new aspire-mstest
dotnet new aspire-nunit
För mer information, se dokumentationen för kommandot .NET CLI dotnet new.
Utforska testprojektet
Följande exempeltestprojekt skapades som en del av mallen .NET.NET Aspire Starter Application. Om du inte känner till det kan du läsa Snabbstart: Skapa ditt första .NET.NET Aspire projekt. Det .NET.NET Aspire testprojektet har ett projektreferensberoende på målappens värd. Överväg mallprojektet:
<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.3" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
<PackageReference Include="xunit" Version="2.9.2" />
<PackageReference Include="xunit.runner.visualstudio" Version="3.0.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="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.7.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="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.5.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>
Den föregående projektfilen är ganska standard. Det finns en PackageReference
till 📦Aspire.Hosting.Testing NuGet-paketet, som innehåller de typer som krävs för att skriva tester för .NET.NET Aspire projekt.
Malltestprojektet innehåller en IntegrationTest1
-klass med ett enda test. Testet verifierar följande scenario:
- Appvärden har lyckosamt skapats och startats.
-
webfrontend
-resursen är tillgänglig och körs. - En HTTP-begäran kan göras till den
webfrontend
resursen och returnerar ett lyckat svar (HTTP 200 OK).
Överväg följande testklass:
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));
}
}
Föregående kod:
- Förlitar sig på DistributedApplicationTestingBuilder.CreateAsync API:et för att asynkront skapa appvärden.
-
appHost
är en instans avIDistributedApplicationTestingBuilder
som representerar appvärden. -
appHost
-instansen har sin tjänstsamling konfigurerad med standardhanteraren för HTTP-motståndskraft. Mer information finns i Skapa motståndskraftiga HTTP-appar: Viktiga utvecklingsmönster.
-
-
appHost
har anropat sin IDistributedApplicationTestingBuilder.BuildAsync(CancellationToken)-metod, som returnerarDistributedApplication
-instansen somapp
.-
app
har sin tjänstleverantör som hämtar ResourceNotificationService-instansen. -
app
startas asynkront.
-
- En HttpClient skapas för den
webfrontend
resursen genom att anropaapp.CreateHttpClient
. -
resourceNotificationService
används för att vänta tillswebfrontend
resurs är tillgänglig och körs. - En enkel HTTP GET-begäran görs till roten för den
webfrontend
resursen. - Testet hävdar att svarsstatuskoden är
OK
.
Testa resursmiljövariabler
För att ytterligare testa resurser och deras uttryckta beroenden i din .NET.NET Aspire lösning kan du kontrollera att miljövariablerna matas in korrekt. I följande exempel visas hur du testar att den webfrontend
resursen har en HTTPS-miljövariabel som matchar den apiservice
resursen:
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}")));
}
}
Föregående kod:
- Förlitar sig på DistributedApplicationTestingBuilder.CreateAsync API:et för att asynkront skapa appvärden.
- Den
builder
instansen används för att hämta en IResourceWithEnvironment-instans med namnet "webfrontend" från IDistributedApplicationTestingBuilder.Resources. - Den
webfrontend
resursen används för att anropa GetEnvironmentVariableValuesAsync för att hämta dess konfigurerade miljövariabler. - Argumentet DistributedApplicationOperation.Publish skickas när
GetEnvironmentVariableValuesAsync
anropas för att ange miljövariabler som publiceras till resursen som bindningsuttryck. - Med de returnerade miljövariablerna hävdar testet att den
webfrontend
resursen har en HTTPS-miljövariabel som matchar denapiservice
resursen.
Sammanfattning
Den .NET Aspire testprojektmallen gör det enklare att skapa testprojekt för .NET Aspire lösningar. Mallprojektet innehåller ett exempeltest som du kan använda som utgångspunkt för dina tester.
DistributedApplicationTestingBuilder
följer ett välbekant mönster för WebApplicationFactory<TEntryPoint> i ASP.NET Core. Det gör att du kan skapa en testvärd för ditt distribuerade program och köra tester mot den.
När du använder DistributedApplicationTestingBuilder
omdirigeras slutligen alla resursloggar till DistributedApplication
som standard. Omdirigeringen av resursloggar möjliggör scenarier där du vill kontrollera att en resurs loggar korrekt.
Se även
.NET Aspire