CommunityCodierung & Entwicklunggithub.com

Aspire-Integrationstests

Schreibe Integrationstests für .NET Aspire-Anwendungen unter Verwendung von xUnit.

Was ist Aspire-Integrationstests?

Diese Fähigkeit ermöglicht es Entwicklern, Integrationstests für .NET Aspire-Anwendungen zu schreiben, die auf echten Abhängigkeiten wie Datenbanken, Caches und Message Queues basieren. Sie nutzt xUnit als Testframework und das `Aspire.Hosting.Testing`-Paket, um verteilte Anwendungen mit dynamischen Ports und Containern zu orchestrieren. Die Fähigkeit beschreibt bewährte Methoden wie dynamische Endpunkt-Erkennung, Health-Checks und parallele Testisolierung, die typische Fallstricke wie Portkonflikte oder File-Descriptor-Limits vermeiden. Sie ist für CI/CD-Umgebungen optimiert und unterstützt sowohl API- als auch UI-Tests mit Playwright.

Funktioniert mit~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/Aaronontheweb/dotnet-skills/tree/main/skills/aspire-integration-testing

Installed? Explore more Codierung & Entwicklung skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

In Ihrer bevorzugten KI fragen

Öffnet einen neuen Chat, in dem dieser Agent-Skill bereits geladen ist.

Dokumentation

Integrationstests mit .NET Aspire + xUnit

Wann diese Fähigkeit verwenden

Verwenden Sie diese Fähigkeit, wenn:

  • Integrationstests für .NET Aspire-Anwendungen schreiben
  • ASP.NET Core-Apps mit echten Datenbankverbindungen testen
  • Service-to-Service-Kommunikation in verteilten Anwendungen verifizieren
  • Testen mit tatsächlicher Infrastruktur (SQL Server, Redis, Message Queues) in Containern
  • Playwright-UI-Tests mit Aspire-orchestrierten Diensten kombinieren
  • Microservices mit korrektem Service-Discovery und Netzwerk testen

Referenzdateien

  • advanced-patterns.md: Endpunkt-Erkennung, Datenbanktests, Playwright, bedingte Konfiguration, Respawn, Service-Kommunikation, Message Queues
  • ci-and-tooling.md: CI/CD-Integration, benutzerdefinierte Resource-Waiter, Aspire CLI mit MCP

Kernprinzipien

  1. Echte Abhängigkeiten – Verwenden Sie tatsächliche Infrastruktur (Datenbanken, Caches) über Aspire, keine Mocks
  2. Dynamische Port-Bindung – Lassen Sie Aspire Ports dynamisch zuweisen (127.0.0.1:0), um Konflikte zu vermeiden
  3. Fixture-Lebenszyklus – Verwenden Sie IAsyncLifetime für die ordnungsgemäße Einrichtung und Bereinigung von Test-Fixtures
  4. Endpunkt-Erkennung – Niemals URLs fest codieren; Endpunkte zur Laufzeit von Aspire abrufen
  5. Parallele Isolation – Verwenden Sie xUnit-Collection-Attribute, um die Test-Parallelisierung zu steuern
  6. Health Checks – Warten Sie immer darauf, dass Dienste gesund sind, bevor Sie Tests ausführen

Hochrangige Testarchitektur

┌─────────────────┐                    ┌──────────────────────┐
│ xUnit-Testdatei  │──verwendet───►  │  AspireFixture       │
└─────────────────┘                    │  (IAsyncLifetime)    │
                                       └──────────────────────┘
                                               │
                                               │ startet
                                               ▼
                                    ┌───────────────────────────┐
                                    │  DistributedApplication  │
                                    │  (von AppHost)           │
                                    └───────────────────────────┘
                                               │ bereitstellt
                                               ▼
                                  ┌──────────────────────────────┐
                                  │   Dynamische HTTP-Endpunkte  │
                                  └──────────────────────────────┘
                                               │ konsumiert von
                                               ▼
                                   ┌─────────────────────────┐
                                   │  HttpClient / Playwright│
                                   └─────────────────────────┘

Erforderliche NuGet-Pakete

<ItemGroup>
  <PackageReference Include="Aspire.Hosting.Testing" Version="$(AspireVersion)" />
  <PackageReference Include="xunit" Version="*" />
  <PackageReference Include="xunit.runner.visualstudio" Version="*" />
  <PackageReference Include="Microsoft.NET.Test.Sdk" Version="*" />
</ItemGroup>

KRITISCH: File-Watcher-Fix für Integrationstests

Wenn viele Integrationstests ausgeführt werden, die jeweils einen IHost starten, aktiviert der standardmäßige .NET Host Builder File Watcher für die Konfigurationsneuladung. Dies führt unter Linux zur Erschöpfung der File-Descriptor-Limits.

Fügen Sie dies Ihrem Testprojekt hinzu, bevor Tests ausgeführt werden:

// TestEnvironmentInitializer.cs
using System.Runtime.CompilerServices;

namespace YourApp.Tests;

internal static class TestEnvironmentInitializer
{
    [ModuleInitializer]
    internal static void Initialize()
    {
        // Deaktiviert die Konfigurationsdatei-Überwachung in Testhosts
        // Verhindert die Erschöpfung von File-Deskriptoren (inotify watch limit) unter Linux
        Environment.SetEnvironmentVariable("DOTNET_HOSTBUILDER__RELOADCONFIGONCHANGE", "false");
    }
}

Muster 1: Basis-Aspire-Test-Fixture (Moderne API)

using Aspire.Hosting;
using Aspire.Hosting.Testing;

public sealed class AspireAppFixture : IAsyncLifetime
{
    private DistributedApplication? _app;

    public DistributedApplication App => _app
        ?? throw new InvalidOperationException("App nicht initialisiert");

    public async Task InitializeAsync()
    {
        var builder = await DistributedApplicationTestingBuilder
            .CreateAsync<Projects.YourApp_AppHost>([
                "YourApp:UseVolumes=false",
                "YourApp:Environment=IntegrationTest",
                "YourApp:Replicas=1"
            ]);

        _app = await builder.BuildAsync();

        using var startupCts = new CancellationTokenSource(TimeSpan.FromMinutes(10));
        await _app.StartAsync(startupCts.Token);

        using var healthCts = new CancellationTokenSource(TimeSpan.FromMinutes(5));
        await _app.ResourceNotifications.WaitForResourceHealthyAsync("api", healthCts.Token);
    }

    public Uri GetEndpoint(string resourceName, string scheme = "https")
    {
        return _app?.GetEndpoint(resourceName, scheme)
            ?? throw new InvalidOperationException($"Endpunkt für '{resourceName}' nicht gefunden");
    }

    public async Task DisposeAsync()
    {
        if (_app is not null)
        {
            await _app.DisposeAsync();
        }
    }
}

Muster 2: Verwendung des Fixtures in Tests

[CollectionDefinition("Aspire-Collection")]
public class AspireCollection : ICollectionFixture<AspireAppFixture> { }

[Collection("Aspire-Collection")]
public class IntegrationTests
{
    private readonly AspireAppFixture _fixture;

    public IntegrationTests(AspireAppFixture fixture)
    {
        _fixture = fixture;
    }

    [Fact]
    public async Task Application_ShouldStart()
    {
        var httpClient = _fixture.App.CreateHttpClient("yourapp");
        var response = await httpClient.GetAsync("/");
        Assert.Equal(HttpStatusCode.OK, response.StatusCode);
    }
}

Weitere Informationen finden Sie in advanced-patterns.md für Endpunkt-Erkennung, Datenbanktests, Playwright-UI-Tests, bedingte Ressourcenkonfiguration, Respawn-Datenbank-Reset, Service-to-Service-Kommunikation und Message-Queue-Testmuster.

Zusammenfassung der gängigen Muster

MusterAnwendungsfall
Basis-FixtureEinfacher HTTP-Endpunkt-Test
Endpunkt-ErkennungVermeidung hartcodierter URLs
DatenbanktestsÜberprüfung der Datenzugriffsschicht
Playwright-IntegrationVollständige UI-Tests mit echtem Backend
KonfigurationsüberschreibungTestspezifische Einstellungen
Health ChecksSicherstellen, dass Dienste bereit sind
Service-KommunikationTesten verteilter Systeminteraktionen
Message-Queue-TestsÜberprüfung asynchroner Nachrichtenübermittlung

Knifflige / Nicht offensichtliche Tipps

ProblemLösung
Tests laufen sofort in ein TimeoutRufen Sie await _app.StartAsync() auf und warten Sie, bis Dienste gesund sind
Portkonflikte zwischen TestsVerwenden Sie xUnit CollectionDefinition, um Fixtures gemeinsam zu nutzen
Flaky-Tests aufgrund von TimingImplementieren Sie ordnungsgemäßes Health-Check-Polling anstelle von Task.Delay()
Keine Verbindung zu SQL Server möglichVerbindungszeichenfolge dynamisch über GetConnectionStringAsync() abrufen
Parallele Tests stören sich gegenseitigVerwenden Sie das [Collection]-Attribut, um zusammengehörige Tests sequenziell auszuführen
Aspire-Dashboard-KonflikteEs kann nur ein Dashboard gleichzeitig laufen; Tests verwenden dieselbe Instanz

Best Practices

  1. Verwenden Sie IAsyncLifetime – Stellt ordnungsgemäße asynchrone Initialisierung und Bereinigung sicher
  2. Teilen Sie Fixtures über Collections – Reduziert die Testausführungszeit durch Wiederverwendung von App-Instanzen
  3. Entdecken Sie Endpunkte dynamisch – Niemals localhost:5000 oder ähnliches hartcodieren
  4. Warten Sie auf Health Checks – Gehen Sie nicht davon aus, dass Dienste sofort bereit sind
  5. Testen Sie mit echten Abhängigkeiten – Aspire macht es einfach, echte SQL-, Redis- usw. zu verwenden
  6. Räumen Sie Ressourcen auf – Implementieren Sie immer DisposeAsync korrekt
  7. Verwenden Sie aussagekräftige Testdaten – Befüllen Sie Datenbanken mit realistischen Testdaten
  8. Testen Sie Fehlerszenarien – Überprüfen Sie Fehlerbehandlung und Resilienz
  9. Halten Sie Tests isoliert – Jeder Test sollte unabhängig und reihenfolgeunabhängig sein
  10. Überwachen Sie die Testlaufzeit – Wenn Tests langsam sind, ziehen Sie Parallelisierung in Betracht

Weitere Informationen finden Sie in ci-and-tooling.md für GitHub Actions-Setup, benutzerdefinierte Resource-Waiter und Aspire CLI/MCP-Integration.


Debugging-Tipps

  1. Führen Sie das Aspire-Dashboard aus – Wenn Tests fehlschlagen, überprüfen Sie das Dashboard unter http://localhost:15888
  2. Verwenden Sie Aspire CLI mit MCP – Lassen Sie KI-Assistenten den tatsächlichen Anwendungsstatus abfragen
  3. Aktivieren Sie detailliertes Logging – Setzen Sie ASPIRE_ALLOW_UNSECURED_TRANSPORT=true für ausführlichere Ausgabe
  4. Überprüfen Sie Container-Logs – Verwenden Sie docker logs, um die Container-Ausgabe zu überprüfen
  5. Setzen Sie Haltepunkte in Fixtures – Debuggen Sie die Fixture-Initialisierung, um Startprobleme zu erkennen
  6. Überprüfen Sie Ressourcennamen – Stellen Sie sicher, dass die Ressourcennamen zwischen AppHost und Tests übereinstimmen

Individual skills in this repo

This repo contains 20 individual skills — each has its own dedicated page.

akka-hosting-actor-patterns

Patterns for building entity actors with Akka.Hosting - GenericChildPerEntityParent, message extractors, cluster sharding abstraction, akka-reminders, and ITimeProvider. Supports both local testing and clustered production modes.

akka-net-aspire-configuration

Configure Akka.NET with .NET Aspire for local development and production deployments. Covers actor system setup, clustering, persistence, Akka.Management integration, and Aspire orchestration patterns.

akka-net-best-practices

Critical Akka.NET best practices including EventStream vs DistributedPubSub, supervision strategies, error handling, Props vs DependencyResolver, work distribution patterns, and cluster/local mode abstractions for testability.

akka-net-management

Akka.Management for cluster bootstrapping, service discovery (Kubernetes, Azure, Config), health checks, and dynamic cluster formation without static seed nodes.

akka-net-testing-patterns

Write unit and integration tests for Akka.NET actors using modern Akka.Hosting.TestKit patterns. Covers dependency injection, TestProbes, persistence testing, and actor interaction verification. Includes guidance on when to use traditional TestKit.

api-design

Design stable, compatible public APIs using extend-only design principles. Manage API compatibility, wire compatibility, and versioning for NuGet packages and distributed systems.

aspire-configuration

Configure Aspire AppHost to emit explicit app config via environment variables; keep app code free of Aspire clients and service discovery.

aspire-service-defaults

Create a shared ServiceDefaults project for Aspire applications. Centralizes OpenTelemetry, health checks, resilience, and service discovery configuration across all services.

crap-analysis

Analyze code coverage and CRAP (Change Risk Anti-Patterns) scores to identify high-risk code. Use OpenCover format with ReportGenerator for Risk Hotspots showing cyclomatic complexity and untested code paths.

csharp-concurrency-patterns

Choosing the right concurrency abstraction in .NET - from async/await for I/O to Channels for producer/consumer to Akka.NET for stateful entity management. Avoid locks and manual synchronization unless absolutely necessary.

database-performance

Database access patterns for performance. Separate read/write models, avoid N+1 queries, use AsNoTracking, apply row limits, and never do application-side joins. Works with EF Core and Dapper.

dependency-injection-patterns

Organize DI registrations using IServiceCollection extension methods. Group related services into composable Add* methods for clean Program.cs and reusable configuration in tests.

dotnet-devcert-trust

Diagnose and fix .NET HTTPS dev certificate trust issues on Linux. Covers the full certificate lifecycle from generation to system CA bundle inclusion, with distro-specific guidance for Ubuntu, Fedora, Arch, and WSL2.

dotnet-local-tools

Managing local .NET tools with dotnet-tools.json for consistent tooling across development environments and CI/CD pipelines.

dotnet-project-structure

Modern .NET project structure including .slnx solution format, Directory.Build.props, central package management, SourceLink, version management with RELEASE_NOTES.md, and SDK pinning with global.json.

dotnet-slopwatch

Use Slopwatch to detect LLM reward hacking in .NET code changes. Run after every code modification to catch disabled tests, suppressed warnings, empty catch blocks, and other shortcuts that mask real problems.

efcore-patterns

Entity Framework Core best practices including NoTracking by default, query splitting for navigation collections, migration management, dedicated migration services, and common pitfalls to avoid.

ilspy-decompile

Understand implementation details of .NET code by decompiling assemblies. Use when you want to see how a .NET API works internally, inspect NuGet package source, view framework implementation, or understand compiled .NET binaries.

mailpit-integration

Test email sending locally using Mailpit with .NET Aspire. Captures all outgoing emails without sending them. View rendered HTML, inspect headers, and verify delivery in integration tests.

marketplace-publishing

Workflow for publishing skills and agents to the dotnet-skills Claude Code marketplace. Covers adding new content, updating plugin.json, validation, and release tagging.

Verwandte Skills