De app-host beheren in .NET.NET Aspire tests
Bij het schrijven van functionele tests of integratietests met .NET.NET Aspireis het efficiënt beheren van de app-host exemplaar cruciaal. De app-host vertegenwoordigt de volledige toepassingsomgeving en kan kostbaar zijn om te maken en te afbreken. In dit artikel wordt uitgelegd hoe u de app-hostexemplaar beheert in uw .NET.NET Aspire testen.
Voor het schrijven van tests met .NET.NET Aspiregebruikt u het 📦 Aspire.Hosting.Testing
NuGet-pakket met enkele helperklassen voor het beheren van het hostexemplaren van de app in uw tests.
De DistributedApplicationTestingBuilder
-klasse gebruiken
In de zelfstudie over het schrijven van uw eerste testhebt u kennisgemaakt met de DistributedApplicationTestingBuilder-klasse die kan worden gebruikt om de app host-instantie te maken.
var appHost = await DistributedApplicationTestingBuilder
.CreateAsync<Projects.AspireApp_AppHost>();
De DistributedApplicationTestingBuilder.CreateAsync<T>
-methode neemt het projecttype van de app-host als een generieke parameter om de app-hostinstantie te creëren. Hoewel deze methode aan het begin van elke test wordt uitgevoerd, is het efficiënter om het app-hostexemplaren eenmaal te maken en deze te delen tussen tests naarmate de testsuite groeit.
Met xUnit implementeert u de IAsyncLifetime-interface op de testklasse ter ondersteuning van asynchrone initialisatie en verwijdering van het hostexemplaren van de app. De methode InitializeAsync
wordt gebruikt om de app-hostinstantie te maken voordat de tests worden uitgevoerd, en de methode DisposeAsync
handelt de app-host af zodra de tests zijn voltooid.
public class WebTests : IAsyncLifetime
{
private DistributedApplication _app;
public async Task InitializeAsync()
{
var appHost = await DistributedApplicationTestingBuilder
.CreateAsync<Projects.AspireApp_AppHost>();
_app = await appHost.BuildAsync();
}
public async Task DisposeAsync() => await _app.DisposeAsync();
[Fact]
public async Task GetWebResourceRootReturnsOkStatusCode()
{
// test code here
}
}
Met MSTest gebruikt u de ClassInitializeAttribute en ClassCleanupAttribute op de statische methoden van de testklasse om de initialisatie en opschoning van de app-hostinstantie te bieden. De ClassInitialize
methode wordt gebruikt om het app-hostexemplaren te maken voordat de tests worden uitgevoerd en de ClassCleanup
methode het hostexemplaren van de app verwijdert zodra de tests zijn voltooid.
[TestClass]
public class WebTests
{
private static DistributedApplication _app;
[ClassInitialize]
public static async Task ClassInitialize(TestContext context)
{
var appHost = await DistributedApplicationTestingBuilder
.CreateAsync<Projects.AspireApp_AppHost>();
_app = await appHost.BuildAsync();
}
[ClassCleanup]
public static async Task ClassCleanup() => await _app.DisposeAsync();
[TestMethod]
public async Task GetWebResourceRootReturnsOkStatusCode()
{
// test code here
}
}
Met NUnit gebruikt u de OneTimeSetUp- en OneTimeTearDown- attributen op methoden van de testklasse om de installatie en het afbreken van de hostexemplaar van de app op te geven. De OneTimeSetUp
methode wordt gebruikt om het app-hostexemplaren te maken voordat de tests worden uitgevoerd en de OneTimeTearDown
methode het hostexemplaren van de app verwijdert zodra de tests zijn voltooid.
public class WebTests
{
private DistributedApplication _app;
[OneTimeSetUp]
public async Task OneTimeSetup()
{
var appHost = await DistributedApplicationTestingBuilder
.CreateAsync<Projects.AspireApp_AppHost>();
_app = await appHost.BuildAsync();
}
[OneTimeTearDown]
public async Task OneTimeTearDown() => await _app.DisposeAsync();
[Test]
public async Task GetWebResourceRootReturnsOkStatusCode()
{
// test code here
}
}
Door de app-host vast te leggen in een veld wanneer de testuitvoering wordt gestart, kunt u deze in elke test openen zonder dat u deze opnieuw hoeft te maken, waardoor de tijd die nodig is om de tests uit te voeren, afneemt. Wanneer de testuitvoering is voltooid, wordt de app-host verwijderd, waarmee alle resources worden opgeschoond die tijdens de testuitvoering zijn gemaakt, zoals containers.
Argumenten doorgeven aan uw app-host
U hebt toegang tot de argumenten van uw app-host met de parameter args
. Argumenten worden ook doorgegeven aan .NETconfiguratiesysteem, zodat u op deze manier veel configuratie-instellingen kunt overschrijven. In het volgende voorbeeld overschrijft u de omgeving door deze op te geven als opdrachtregeloptie:
var builder = await DistributedApplicationTestingBuilder
.CreateAsync<Projects.MyAppHost>(
[
"--environment=Testing"
]);
Andere argumenten kunnen worden doorgegeven aan uw app-host Program
en beschikbaar worden gesteld in uw app-host. In het volgende voorbeeld geeft u een argument door aan de app-host en gebruikt u dit om te bepalen of u gegevensvolumes toevoegt aan een Postgres exemplaar.
In de app-host Program
gebruikt u configuratie ter ondersteuning van het in- of uitschakelen van volumes:
var postgres = builder.AddPostgres("postgres1");
if (builder.Configuration.GetValue("UseVolumes", true))
{
postgres.WithDataVolume();
}
In testcode geeft u "UseVolumes=false"
via de args
aan de app-host door.
public async Task DisableVolumesFromTest()
{
// Disable volumes in the test builder via arguments:
using var builder = await DistributedApplicationTestingBuilder
.CreateAsync<Projects.TestingAppHost1_AppHost>(
[
"UseVolumes=false"
]);
// The container will have no volume annotation since we disabled volumes by passing UseVolumes=false
var postgres = builder.Resources.Single(r => r.Name == "postgres1");
Assert.Empty(postgres.Annotations.OfType<ContainerMountAnnotation>());
}
De DistributedApplicationFactory
-klasse gebruiken
Hoewel de DistributedApplicationTestingBuilder
-klasse nuttig is voor veel scenario's, zijn er mogelijk situaties waarin u meer controle wilt over het starten van de app-host, zoals het uitvoeren van code voordat de opbouwfunctie wordt gemaakt of nadat de app-host is gebouwd. In deze gevallen implementeert u uw eigen versie van de DistributedApplicationFactory-klasse. Dit is wat de DistributedApplicationTestingBuilder
intern gebruikt.
public class TestingAspireAppHost()
: DistributedApplicationFactory(typeof(Projects.AspireApp_AppHost))
{
// override methods here
}
De constructor vereist het type referentie van het app-hostproject als parameter. U kunt desgewenst argumenten opgeven voor de onderliggende opbouwfunctie voor hosttoepassingen. Deze argumenten bepalen hoe de app-host wordt gestart en waarden opgeven voor de argsvariabele die door het Program.cs-bestand wordt gebruikt om het hostexemplaren van de app te starten.
Levenscyclusmethoden
De DistributionApplicationFactory
-klasse biedt verschillende levenscyclusmethoden die kunnen worden overschreven om aangepast gedrag te bieden tijdens de voorbereiding en het maken van de app-host. De beschikbare methoden zijn OnBuilderCreating
, OnBuilderCreated
, OnBuilding
en OnBuilt
.
We kunnen bijvoorbeeld de OnBuilderCreating
methode gebruiken om configuratie in te stellen, zoals de gegevens van het abonnement en de resourcegroep voor Azure, voordat de app-host wordt gemaakt en eventuele afhankelijke Azure resources worden ingericht, wat resulteert in onze tests met behulp van de juiste Azure omgeving.
public class TestingAspireAppHost() : DistributedApplicationFactory(typeof(Projects.AspireApp_AppHost))
{
protected override void OnBuilderCreating(DistributedApplicationOptions applicationOptions, HostApplicationBuilderSettings hostOptions)
{
hostOptions.Configuration ??= new();
hostOptions.Configuration["environment"] = "Development";
hostOptions.Configuration["AZURE_SUBSCRIPTION_ID"] = "00000000-0000-0000-0000-000000000000";
hostOptions.Configuration["AZURE_RESOURCE_GROUP"] = "my-resource-group";
}
}
Vanwege de volgorde van prioriteit in het .NET configuratiesysteem worden de omgevingsvariabelen gebruikt voor alles in het appsettings.json- of secrets.json-bestand.
Een ander scenario dat u in de levenscyclus wilt gebruiken, is het configureren van de services die door de app-host worden gebruikt. In het volgende voorbeeld kunt u een scenario overwegen waarin u de OnBuilderCreated
-API overschrijft om tolerantie toe te voegen aan de HttpClient
:
protected override void OnBuilderCreated(
DistributedApplicationBuilder applicationBuilder)
{
applicationBuilder.Services.ConfigureHttpClientDefaults(clientBuilder =>
{
clientBuilder.AddStandardResilienceHandler();
});
}