Communityコーディング&開発github.com

aspire-integration-testing

.NET Aspire アプリケーションの統合テストを作成するためのスキル

aspire-integration-testing とは?

このスキルは、.NET Aspire を使用した分散アプリケーションの統合テストを支援します。xUnit テストフレームワークを基盤とし、実際のデータベースやコンテナ化されたインフラ(SQL Server、Redis、メッセージキュー)を使ってサービス間通信やデータアクセス層をテストできます。Aspire の動的ポートバインディングとエンドポイント検出機能により、ハードコードされたURLを排除し、並列実行時のポート競合を防ぎます。Playwright を組み合わせたUIテストや、CI/CDパイプラインへの統合もサポートしており、実用的な統合テストパターンと非自明なヒントが豊富に含まれています。

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

Installed? Explore more コーディング&開発 skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

お気に入りのAIに質問する

このエージェントスキルを事前に読み込んだ状態で新しいチャットを開きます。

ドキュメント

.NET Aspire + xUnit による統合テスト

このスキルを使用するタイミング

以下の場合にこのスキルを使用します:

  • .NET Aspire アプリケーションの統合テストを作成する場合
  • 実際のデータベース接続を使用して ASP.NET Core アプリをテストする場合
  • 分散アプリケーションにおけるサービス間通信を検証する場合
  • コンテナ内の実際のインフラ(SQL Server、Redis、メッセージキュー)を使用したテストを行う場合
  • Playwright UI テストと Aspire でオーケストレーションされたサービスを組み合わせる場合
  • 適切なサービス検出とネットワークを備えたマイクロサービスをテストする場合

参照ファイル

  • advanced-patterns.md:エンドポイント検出、データベーステスト、Playwright、条件付き設定、Respawn、サービス通信、メッセージキュー
  • ci-and-tooling.md:CI/CD 統合、カスタムリソースウェイター、MCP を使用した Aspire CLI

基本原則

  1. 実際の依存関係 - モックではなく、Aspire を介して実際のインフラ(データベース、キャッシュ)を使用する
  2. 動的ポートバインディング - 競合を避けるために、Aspire にポートを動的に割り当てさせる(127.0.0.1:0)
  3. フィクスチャのライフサイクル - 適切なテストフィクスチャのセットアップとティアダウンに IAsyncLifetime を使用する
  4. エンドポイント検出 - URL をハードコードせず、実行時に Aspire からエンドポイントを取得する
  5. 並列実行の分離 - xUnit のコレクションを使用してテストの並列化を制御する
  6. ヘルスチェック - テストを実行する前に、サービスが正常であることを必ず確認する

高レベルテストアーキテクチャ

┌─────────────────┐                    ┌──────────────────────┐
│ xUnit テストファイル │──使用───►│  AspireFixture       │
└─────────────────┘                    │  (IAsyncLifetime)    │
                                       └──────────────────────┘
                                               │
                                               │ 起動
                                               ▼
                                    ┌───────────────────────────┐
                                    │  DistributedApplication   │
                                    │  (AppHost から)           │
                                    └───────────────────────────┘
                                               │ 公開
                                               ▼
                                  ┌──────────────────────────────┐
                                  │   動的 HTTP エンドポイント    │
                                  └──────────────────────────────┘
                                               │ 消費
                                               ▼
                                   ┌─────────────────────────┐
                                   │  HttpClient / Playwright│
                                   └─────────────────────────┘

必須 NuGet パッケージ

<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>

重要: 統合テストのファイルウォッチャー修正

多くの統合テストを実行し、それぞれが IHost を起動すると、デフォルトの .NET ホストビルダーは設定再読み込みのためにファイルウォッチャーを有効にします。これにより、Linux でファイル記述子の制限が枯渇します。

テストを実行する前に、テストプロジェクトに以下を追加してください:

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

namespace YourApp.Tests;

internal static class TestEnvironmentInitializer
{
    [ModuleInitializer]
    internal static void Initialize()
    {
        // テストホストでの設定ファイル監視を無効化
        // Linux でのファイル記述子枯渇(inotify 監視上限)を防止
        Environment.SetEnvironmentVariable("DOTNET_HOSTBUILDER__RELOADCONFIGONCHANGE", "false");
    }
}

パターン1: 基本的な Aspire テストフィクスチャ(モダン API)

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

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

    public DistributedApplication App => _app
        ?? throw new InvalidOperationException("アプリが初期化されていません");

    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($"'{resourceName}' のエンドポイントが見つかりません");
    }

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

パターン2: テストでのフィクスチャの使用

[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);
    }
}

詳細なパターン(エンドポイント検出、データベーステスト、Playwright UI テスト、条件付きリソース設定、Respawn によるデータベースリセット、サービス間通信、メッセージキューテスト)については、advanced-patterns.md を参照してください。

一般的なパターンまとめ

パターンユースケース
基本的なフィクスチャシンプルな HTTP エンドポイントテスト
エンドポイント検出ハードコードされた URL を回避
データベーステストデータアクセス層の検証
Playwright 統合実際のバックエンドを使用した完全 UI テスト
設定のオーバーライドテスト固有の設定
ヘルスチェックサービスが準備完了であることを確認
サービス通信分散システムの相互作用をテスト
メッセージキューテスト非同期メッセージングの検証

直感的でない / 注意すべきヒント

問題解決策
テストがすぐにタイムアウトするawait _app.StartAsync() を呼び出し、サービスが正常になるのを待つ
テスト間のポート競合xUnit の CollectionDefinition を使用してフィクスチャを共有する
タイミングによる不安定なテストTask.Delay() ではなく、適切なヘルスチェックポーリングを実装する
SQL Server に接続できないGetConnectionStringAsync() を使用して動的に接続文字列を取得する
並列テストが干渉する[Collection] 属性を使用して関連テストを逐次実行する
Aspire ダッシュボードの競合同時に実行できるダッシュボードは1つのみ。テストは同じインスタンスを再利用する

ベストプラクティス

  1. IAsyncLifetime を使用する - 非同期の初期化とクリーンアップを確実に行う
  2. コレクションを介してフィクスチャを共有する - アプリインスタンスを再利用してテスト実行時間を短縮する
  3. エンドポイントを動的に取得する - localhost:5000 などをハードコードしない
  4. ヘルスチェックを待つ - サービスがすぐに準備できると想定しない
  5. 実際の依存関係でテストする - Aspire を使用すると、実際の SQL、Redis などを簡単に使用できる
  6. リソースをクリーンアップする - 常に DisposeAsync を適切に実装する
  7. 意味のあるテストデータを使用する - データベースに現実的なテストデータをシードする
  8. 障害シナリオをテストする - エラーハンドリングと回復力を検証する
  9. テストを分離する - 各テストは独立しており、順序に依存しないようにする
  10. テスト実行時間を監視する - テストが遅い場合は、並列化を検討する

GitHub Actions のセットアップ、カスタムリソースウェイター、Aspire CLI/MCP 統合については ci-and-tooling.md を参照してください。


デバッグのヒント

  1. Aspire ダッシュボードを実行する - テストが失敗した場合、http://localhost:15888 でダッシュボードを確認する
  2. MCP と共に Aspire CLI を使用する - AI アシスタントに実際のアプリケーション状態を問い合わせさせる
  3. 詳細なログを有効にする - ASPIRE_ALLOW_UNSECURED_TRANSPORT=true を設定してより詳細な出力を得る
  4. コンテナログを確認する - docker logs を使用してコンテナの出力を検査する
  5. フィクスチャにブレークポイントを設定する - フィクスチャの初期化をデバッグして起動問題を捉える
  6. リソース名を確認する - AppHost とテスト間でリソース名が一致していることを確認する

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.

関連スキル