Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
e250148
feat: add TUnit.Aspire package for Aspire distributed app testing
thomhurst Feb 15, 2026
bf85a9c
refactor: update Aspire test template and CloudShop example to use TU…
thomhurst Feb 15, 2026
7169e61
fix: add fail-fast and timeout diagnostics to AspireFixture
thomhurst Feb 15, 2026
8103bc1
feat: surface resource logs in startup failure and timeout errors
thomhurst Feb 15, 2026
ba9bddc
fix: swap TUnit.Aspire PackageReference for ProjectReference in templ…
thomhurst Feb 15, 2026
5f93049
fix: update public API snapshots for TUnit.Aspire InternalsVisibleTo
thomhurst Feb 15, 2026
e738ef5
fix: pre-pull Docker images and increase timeouts for CloudShop CI
thomhurst Feb 15, 2026
fd4ef42
feat: add progress logging to AspireFixture initialization
thomhurst Feb 15, 2026
3719a15
fix: write progress logs directly to raw stderr stream
thomhurst Feb 15, 2026
555f777
fix: pre-pull exact Aspire 13.1.1 Docker image tags
thomhurst Feb 15, 2026
5c76833
fix: add timeout to StartAsync and set env var earlier
thomhurst Feb 15, 2026
c982bb5
fix: disable TLS on Redis container for CI compatibility
thomhurst Feb 15, 2026
4100309
feat: add real-time resource monitoring and log collection on startup…
thomhurst Feb 15, 2026
4995aeb
chore: remove Docker image pre-pull step from CloudShop CI
thomhurst Feb 15, 2026
e15a566
docs: add comprehensive TUnit.Aspire documentation
thomhurst Feb 15, 2026
ba8b18b
feat: make InitializeAsync and DisposeAsync virtual
thomhurst Feb 15, 2026
6b31ef8
fix: update Aspire Starter template snapshot files
thomhurst Feb 15, 2026
c893ee8
fix: update template snapshot verified files for TUnit.Aspire changes
thomhurst Feb 15, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .github/workflows/cloudshop-example.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:
runs-on: ubuntu-latest
permissions:
contents: read
timeout-minutes: 10
timeout-minutes: 15

steps:
- uses: actions/checkout@v6
Expand All @@ -36,3 +36,5 @@ jobs:

- name: Run integration tests
run: dotnet run --project examples/CloudShop/CloudShop.Tests/CloudShop.Tests.csproj -c Release --no-build
env:
ASPIRE_ALLOW_UNSECURED_TRANSPORT: "true"
1 change: 1 addition & 0 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
</GlobalPackageReference>
</ItemGroup>
<ItemGroup>
<PackageVersion Include="Aspire.Hosting.Testing" Version="13.1.1" />
<PackageVersion Include="AutoFixture" Version="4.18.1" />
<PackageVersion Include="BenchmarkDotNet" Version="0.15.8" />
<PackageVersion Include="BenchmarkDotNet.Annotations" Version="0.15.8" />
Expand Down
507 changes: 507 additions & 0 deletions TUnit.Aspire/AspireFixture.cs

Large diffs are not rendered by default.

27 changes: 27 additions & 0 deletions TUnit.Aspire/ResourceWaitBehavior.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
namespace TUnit.Aspire;

/// <summary>
/// Specifies how <see cref="AspireFixture{TAppHost}"/> should wait for resources during initialization.
/// </summary>
public enum ResourceWaitBehavior
{
/// <summary>
/// Wait for all resources to pass health checks (default).
/// </summary>
AllHealthy,

/// <summary>
/// Wait for all resources to reach the Running state.
/// </summary>
AllRunning,

/// <summary>
/// Wait only for resources returned by <see cref="AspireFixture{TAppHost}.ResourcesToWaitFor"/>.
/// </summary>
Named,

/// <summary>
/// Don't wait for any resources - the user handles readiness manually.
/// </summary>
None
}
25 changes: 25 additions & 0 deletions TUnit.Aspire/TUnit.Aspire.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<Project Sdk="Microsoft.NET.Sdk">

<Import Project="..\Library.props" />

<PropertyGroup>
<TargetFrameworks>net8.0;net9.0;net10.0</TargetFrameworks>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\TUnit\TUnit.csproj" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Aspire.Hosting.Testing" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\TUnit.Analyzers\TUnit.Analyzers.csproj" OutputItemType="Analyzer"
ReferenceOutputAssembly="false" />
<ProjectReference Include="..\TUnit.Core.SourceGenerator\TUnit.Core.SourceGenerator.csproj"
OutputItemType="Analyzer" ReferenceOutputAssembly="false" />
</ItemGroup>

<Import Project="..\Library.targets" />
</Project>
1 change: 1 addition & 0 deletions TUnit.Core/TUnit.Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
<InternalsVisibleTo Include="TUnit.UnitTests" />
<InternalsVisibleTo Include="TUnit.AspNetCore" />
<InternalsVisibleTo Include="TUnit.Logging.Microsoft" />
<InternalsVisibleTo Include="TUnit.Aspire" />
</ItemGroup>

<ItemGroup>
Expand Down
1 change: 1 addition & 0 deletions TUnit.Pipeline/Modules/GetPackageProjectsModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ public class GetPackageProjectsModule : Module<List<File>>
Sourcy.DotNet.Projects.TUnit_Templates,
Sourcy.DotNet.Projects.TUnit_Logging_Microsoft,
Sourcy.DotNet.Projects.TUnit_AspNetCore,
Sourcy.DotNet.Projects.TUnit_Aspire,
Sourcy.DotNet.Projects.TUnit_FsCheck
];
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
[assembly: .(@", PublicKey=0024000004800000940000000602000000240000525341310004000001000100698a70398fa0b2230c5a72e3bd9d56b48f809f6173e49a19fbb942d621be93ad48c5566b47b28faabc359b9ad3ff4e00bbdea88f5bdfa250f391fedd28182b2e37b55d429c0151a42a98ea7a5821818cd15a79fef9903e8607a88304cf3e0317bf86ec96e32e1381535a6582251e5a6eed40b5a3ed82bc444598b1269cce57a7")]
[assembly: .(@", PublicKey=0024000004800000940000000602000000240000525341310004000001000100698a70398fa0b2230c5a72e3bd9d56b48f809f6173e49a19fbb942d621be93ad48c5566b47b28faabc359b9ad3ff4e00bbdea88f5bdfa250f391fedd28182b2e37b55d429c0151a42a98ea7a5821818cd15a79fef9903e8607a88304cf3e0317bf86ec96e32e1381535a6582251e5a6eed40b5a3ed82bc444598b1269cce57a7")]
[assembly: .(@", PublicKey=0024000004800000940000000602000000240000525341310004000001000100698a70398fa0b2230c5a72e3bd9d56b48f809f6173e49a19fbb942d621be93ad48c5566b47b28faabc359b9ad3ff4e00bbdea88f5bdfa250f391fedd28182b2e37b55d429c0151a42a98ea7a5821818cd15a79fef9903e8607a88304cf3e0317bf86ec96e32e1381535a6582251e5a6eed40b5a3ed82bc444598b1269cce57a7")]
[assembly: .(@".Microsoft, PublicKey=0024000004800000940000000602000000240000525341310004000001000100698a70398fa0b2230c5a72e3bd9d56b48f809f6173e49a19fbb942d621be93ad48c5566b47b28faabc359b9ad3ff4e00bbdea88f5bdfa250f391fedd28182b2e37b55d429c0151a42a98ea7a5821818cd15a79fef9903e8607a88304cf3e0317bf86ec96e32e1381535a6582251e5a6eed40b5a3ed82bc444598b1269cce57a7")]
[assembly: .(@", PublicKey=0024000004800000940000000602000000240000525341310004000001000100698a70398fa0b2230c5a72e3bd9d56b48f809f6173e49a19fbb942d621be93ad48c5566b47b28faabc359b9ad3ff4e00bbdea88f5bdfa250f391fedd28182b2e37b55d429c0151a42a98ea7a5821818cd15a79fef9903e8607a88304cf3e0317bf86ec96e32e1381535a6582251e5a6eed40b5a3ed82bc444598b1269cce57a7")]
[assembly: .(".NETCoreApp,Version=v10.0", FrameworkDisplayName=".NET 10.0")]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
[assembly: .(@", PublicKey=0024000004800000940000000602000000240000525341310004000001000100698a70398fa0b2230c5a72e3bd9d56b48f809f6173e49a19fbb942d621be93ad48c5566b47b28faabc359b9ad3ff4e00bbdea88f5bdfa250f391fedd28182b2e37b55d429c0151a42a98ea7a5821818cd15a79fef9903e8607a88304cf3e0317bf86ec96e32e1381535a6582251e5a6eed40b5a3ed82bc444598b1269cce57a7")]
[assembly: .(@", PublicKey=0024000004800000940000000602000000240000525341310004000001000100698a70398fa0b2230c5a72e3bd9d56b48f809f6173e49a19fbb942d621be93ad48c5566b47b28faabc359b9ad3ff4e00bbdea88f5bdfa250f391fedd28182b2e37b55d429c0151a42a98ea7a5821818cd15a79fef9903e8607a88304cf3e0317bf86ec96e32e1381535a6582251e5a6eed40b5a3ed82bc444598b1269cce57a7")]
[assembly: .(@", PublicKey=0024000004800000940000000602000000240000525341310004000001000100698a70398fa0b2230c5a72e3bd9d56b48f809f6173e49a19fbb942d621be93ad48c5566b47b28faabc359b9ad3ff4e00bbdea88f5bdfa250f391fedd28182b2e37b55d429c0151a42a98ea7a5821818cd15a79fef9903e8607a88304cf3e0317bf86ec96e32e1381535a6582251e5a6eed40b5a3ed82bc444598b1269cce57a7")]
[assembly: .(@".Microsoft, PublicKey=0024000004800000940000000602000000240000525341310004000001000100698a70398fa0b2230c5a72e3bd9d56b48f809f6173e49a19fbb942d621be93ad48c5566b47b28faabc359b9ad3ff4e00bbdea88f5bdfa250f391fedd28182b2e37b55d429c0151a42a98ea7a5821818cd15a79fef9903e8607a88304cf3e0317bf86ec96e32e1381535a6582251e5a6eed40b5a3ed82bc444598b1269cce57a7")]
[assembly: .(@", PublicKey=0024000004800000940000000602000000240000525341310004000001000100698a70398fa0b2230c5a72e3bd9d56b48f809f6173e49a19fbb942d621be93ad48c5566b47b28faabc359b9ad3ff4e00bbdea88f5bdfa250f391fedd28182b2e37b55d429c0151a42a98ea7a5821818cd15a79fef9903e8607a88304cf3e0317bf86ec96e32e1381535a6582251e5a6eed40b5a3ed82bc444598b1269cce57a7")]
[assembly: .(".NETCoreApp,Version=v8.0", FrameworkDisplayName=".NET 8.0")]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
[assembly: .(@", PublicKey=0024000004800000940000000602000000240000525341310004000001000100698a70398fa0b2230c5a72e3bd9d56b48f809f6173e49a19fbb942d621be93ad48c5566b47b28faabc359b9ad3ff4e00bbdea88f5bdfa250f391fedd28182b2e37b55d429c0151a42a98ea7a5821818cd15a79fef9903e8607a88304cf3e0317bf86ec96e32e1381535a6582251e5a6eed40b5a3ed82bc444598b1269cce57a7")]
[assembly: .(@", PublicKey=0024000004800000940000000602000000240000525341310004000001000100698a70398fa0b2230c5a72e3bd9d56b48f809f6173e49a19fbb942d621be93ad48c5566b47b28faabc359b9ad3ff4e00bbdea88f5bdfa250f391fedd28182b2e37b55d429c0151a42a98ea7a5821818cd15a79fef9903e8607a88304cf3e0317bf86ec96e32e1381535a6582251e5a6eed40b5a3ed82bc444598b1269cce57a7")]
[assembly: .(@", PublicKey=0024000004800000940000000602000000240000525341310004000001000100698a70398fa0b2230c5a72e3bd9d56b48f809f6173e49a19fbb942d621be93ad48c5566b47b28faabc359b9ad3ff4e00bbdea88f5bdfa250f391fedd28182b2e37b55d429c0151a42a98ea7a5821818cd15a79fef9903e8607a88304cf3e0317bf86ec96e32e1381535a6582251e5a6eed40b5a3ed82bc444598b1269cce57a7")]
[assembly: .(@".Microsoft, PublicKey=0024000004800000940000000602000000240000525341310004000001000100698a70398fa0b2230c5a72e3bd9d56b48f809f6173e49a19fbb942d621be93ad48c5566b47b28faabc359b9ad3ff4e00bbdea88f5bdfa250f391fedd28182b2e37b55d429c0151a42a98ea7a5821818cd15a79fef9903e8607a88304cf3e0317bf86ec96e32e1381535a6582251e5a6eed40b5a3ed82bc444598b1269cce57a7")]
[assembly: .(@", PublicKey=0024000004800000940000000602000000240000525341310004000001000100698a70398fa0b2230c5a72e3bd9d56b48f809f6173e49a19fbb942d621be93ad48c5566b47b28faabc359b9ad3ff4e00bbdea88f5bdfa250f391fedd28182b2e37b55d429c0151a42a98ea7a5821818cd15a79fef9903e8607a88304cf3e0317bf86ec96e32e1381535a6582251e5a6eed40b5a3ed82bc444598b1269cce57a7")]
[assembly: .(".NETCoreApp,Version=v9.0", FrameworkDisplayName=".NET 9.0")]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
[assembly: .(@", PublicKey=0024000004800000940000000602000000240000525341310004000001000100698a70398fa0b2230c5a72e3bd9d56b48f809f6173e49a19fbb942d621be93ad48c5566b47b28faabc359b9ad3ff4e00bbdea88f5bdfa250f391fedd28182b2e37b55d429c0151a42a98ea7a5821818cd15a79fef9903e8607a88304cf3e0317bf86ec96e32e1381535a6582251e5a6eed40b5a3ed82bc444598b1269cce57a7")]
[assembly: .(@", PublicKey=0024000004800000940000000602000000240000525341310004000001000100698a70398fa0b2230c5a72e3bd9d56b48f809f6173e49a19fbb942d621be93ad48c5566b47b28faabc359b9ad3ff4e00bbdea88f5bdfa250f391fedd28182b2e37b55d429c0151a42a98ea7a5821818cd15a79fef9903e8607a88304cf3e0317bf86ec96e32e1381535a6582251e5a6eed40b5a3ed82bc444598b1269cce57a7")]
[assembly: .(@", PublicKey=0024000004800000940000000602000000240000525341310004000001000100698a70398fa0b2230c5a72e3bd9d56b48f809f6173e49a19fbb942d621be93ad48c5566b47b28faabc359b9ad3ff4e00bbdea88f5bdfa250f391fedd28182b2e37b55d429c0151a42a98ea7a5821818cd15a79fef9903e8607a88304cf3e0317bf86ec96e32e1381535a6582251e5a6eed40b5a3ed82bc444598b1269cce57a7")]
[assembly: .(@".Microsoft, PublicKey=0024000004800000940000000602000000240000525341310004000001000100698a70398fa0b2230c5a72e3bd9d56b48f809f6173e49a19fbb942d621be93ad48c5566b47b28faabc359b9ad3ff4e00bbdea88f5bdfa250f391fedd28182b2e37b55d429c0151a42a98ea7a5821818cd15a79fef9903e8607a88304cf3e0317bf86ec96e32e1381535a6582251e5a6eed40b5a3ed82bc444598b1269cce57a7")]
[assembly: .(@", PublicKey=0024000004800000940000000602000000240000525341310004000001000100698a70398fa0b2230c5a72e3bd9d56b48f809f6173e49a19fbb942d621be93ad48c5566b47b28faabc359b9ad3ff4e00bbdea88f5bdfa250f391fedd28182b2e37b55d429c0151a42a98ea7a5821818cd15a79fef9903e8607a88304cf3e0317bf86ec96e32e1381535a6582251e5a6eed40b5a3ed82bc444598b1269cce57a7")]
[assembly: .(".NETStandard,Version=v2.0", FrameworkDisplayName=".NET Standard 2.0")]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using TUnit.Aspire;

namespace TUnit.Aspire.Starter.TestProject;

public class AppFixture : AspireFixture<Projects.TUnit.Aspire.Starter_AppHost>
{
protected override void ConfigureBuilder(IDistributedApplicationTestingBuilder builder)
{
builder.Services.ConfigureHttpClientDefaults(clientBuilder =>
{
clientBuilder.AddStandardResilienceHandler();
});
}
}

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
Expand All @@ -8,13 +8,10 @@
<IsTestProject>true</IsTestProject>
</PropertyGroup>


<ItemGroup>
<PackageReference Include="Aspire.Hosting.Testing" Version="1.0.0" />
<PackageReference Include="TUnit" Version="1.0.0" />
<PackageReference Include="TUnit.Aspire" Version="1.0.0" />
</ItemGroup>


<ItemGroup>
<ProjectReference Include="..\TUnit.Aspire.Starter.AppHost\TUnit.Aspire.Starter.AppHost.csproj" />
</ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
using System.Text.Json;
using TUnit.Aspire.Starter.TestProject.Data;
using System.Text.Json;
using TUnit.Aspire.Starter.TestProject.Models;

namespace TUnit.Aspire.Starter.TestProject.Tests;

[ClassDataSource<HttpClientDataClass>]
public class ApiTests(HttpClientDataClass httpClientData)
[ClassDataSource<AppFixture>(Shared = SharedType.PerTestSession)]
public class ApiTests(AppFixture fixture)
{
[Test]
public async Task GetWeatherForecastReturnsOkStatusCode()
{
// Arrange
var httpClient = httpClientData.HttpClient;
var httpClient = fixture.CreateHttpClient("apiservice");
// Act
var response = await httpClient.GetAsync("/weatherforecast");
// Assert
Expand All @@ -25,7 +24,7 @@ public async Task GetWeatherForecastReturnsCorrectData(
)
{
// Arrange
var httpClient = httpClientData.HttpClient;
var httpClient = fixture.CreateHttpClient("apiservice");
// Act
var response = await httpClient.GetAsync("/weatherforecast");
var content = await response.Content.ReadAsStringAsync();
Expand Down

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,26 +1,43 @@
namespace TUnit.Aspire.Test
using TUnit.Aspire;

namespace TUnit.Aspire.Test;

// Instructions:
// 1. Add a project reference to the target AppHost project, e.g.:
//
// <ItemGroup>
// <ProjectReference Include="../MyAspireApp.AppHost/MyAspireApp.AppHost.csproj" />
// </ItemGroup>
//
// 2. Create a fixture class for your AppHost (or use AspireFixture directly):
//
// public class AppFixture : AspireFixture<Projects.MyAspireApp_AppHost>
// {
// protected override void ConfigureBuilder(IDistributedApplicationTestingBuilder builder)
// {
// builder.Services.ConfigureHttpClientDefaults(clientBuilder =>
// {
// clientBuilder.AddStandardResilienceHandler();
// });
// }
// }
//
// 3. Uncomment the following example test and update 'AppFixture' to match your fixture:
//
//[ClassDataSource<AppFixture>(Shared = SharedType.PerTestSession)]
//public class IntegrationTest1(AppFixture fixture)
//{
// [Test]
// public async Task GetWebResourceRootReturnsOkStatusCode()
// {
// // Arrange
// var httpClient = fixture.CreateHttpClient("webfrontend");
// // Act
// var response = await httpClient.GetAsync("/");
// // Assert
// await Assert.That(response.StatusCode).IsEqualTo(HttpStatusCode.OK);
// }
//}
public class IntegrationTest1
{
public class IntegrationTest1
{
// Instructions:
// 1. Add a project reference to the target AppHost project, e.g.:
//
// <ItemGroup>
// <ProjectReference Include="../MyAspireApp.AppHost/MyAspireApp.AppHost.csproj" />
// </ItemGroup>
//
// 2. Uncomment the following example test and update 'Projects.MyAspireApp_AppHost' in GlobalSetup.cs to match your AppHost project:
//
//[ClassDataSource<HttpClientDataClass>]
//[Test]
//public async Task GetWebResourceRootReturnsOkStatusCode(HttpClientDataClass httpClientData)
//{
// // Arrange
// var httpClient = httpClientData.HttpClient;
// // Act
// var response = await httpClient.GetAsync("/");
// // Assert
// await Assert.That(response.StatusCode).IsEqualTo(HttpStatusCode.OK);
//}
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
Expand All @@ -9,8 +9,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Aspire.Hosting.Testing" Version="1.0.0" />
<PackageReference Include="TUnit" Version="1.0.0" />
<PackageReference Include="TUnit.Aspire" Version="1.0.0" />
</ItemGroup>

<ItemGroup>
Expand Down
Loading
Loading