Full-stack acceptance testing with Aspire.Hosting.Testing — launching entire AppHost including containers
When you need to test the entire Aspire-orchestrated application — all services, containers, and infrastructure — rather than individual services in isolation. Useful for end-to-end acceptance tests that verify cross-service behavior.
var builder = await DistributedApplicationTestingBuilder.CreateAsync<Projects.AppHost>();
_app = await builder.BuildAsync();
await _app.StartAsync();
This launches the full AppHost including all AddProject, AddContainer, AddPostgres, AddRedis etc.
var apiEndpoint = _app.GetEndpoint("bridge-api", "http");
var httpClient = new HttpClient { BaseAddress = new Uri(apiEndpoint.ToString()) };
var redisConnStr = await _app.GetConnectionStringAsync("redis");
var redis = await ConnectionMultiplexer.ConnectAsync(redisConnStr);
[CollectionDefinition("FullStack")]
public sealed class FullStackCollection : ICollectionFixture<FullStackFixture> { }
[Collection("FullStack")]
public class MyTests : IClassFixture<FullStackFixture> { }
All tests in the same collection share one fixture instance and run serially.
var retryPolicy = Policy
.Handle<HttpRequestException>()
.WaitAndRetryAsync(36, _ => TimeSpan.FromSeconds(5));
await retryPolicy.ExecuteAsync(async () => {
var response = await httpClient.GetAsync("/");
response.EnsureSuccessStatusCode();
});
while (!cts.IsCancellationRequested)
{
var length = await db.ListLengthAsync("queue:worldgen");
if (length == 0) {
await Task.Delay(2000, cts.Token); // Let in-progress job finish
if (await db.ListLengthAsync("queue:worldgen") == 0) return;
}
await Task.Delay(3000, cts.Token);
}
<PackageReference Include="Aspire.Hosting.Testing" Version="13.1.0" />
<PackageReference Include="Polly" Version="8.5.2" />
<RunSettings>
<RunConfiguration>
<TestSessionTimeout>600000</TestSessionTimeout>
</RunConfiguration>
<xUnit>
<MaxParallelThreads>1</MaxParallelThreads>
<ParallelizeTestCollections>false</ParallelizeTestCollections>
</xUnit>
</RunSettings>