Token导航 LogoToken导航TokenDH.com
运维和基础设施需要联网github未标认证来源可访问clear审计通过

dotnet-testing-advanced-aspire-testingdotnet 测试高级 aspire 测试

Agent Skill

用于辅助测试设计、自动化测试、用例整理和回归验证。它适合让 Agent 编写单元测试、端到端测试、测试计划或根据失败日志定位问题。使用时需要确认项目测试框架、运行命令和夹具数据,避免为了通过测试而改坏真实逻辑;涉及浏览器或外部服务时,应区分本地模拟、测试环境和生产环境。

总安装

661

周安装

27

GitHub Stars

24

下载量

212
CodexClaudeCursorGemini CLI

安装说明

本站只整理中文说明和来源信息,不托管安装包,也不代用户安装。

GitHub

来源数

3

许可证

MIT

最后核验

2026-05-01

来源状态

来源可访问

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:dotnet-testing-advanced-aspire-testing(dotnet 测试高级 aspire 测试)
来源仓库:https://github.com/kevintsengtw/dotnet-testing-agent-skills
仓库路径:skills/dotnet-testing-advanced-aspire-testing
安装命令:
npx skills add https://github.com/kevintsengtw/dotnet-testing-agent-skills --skill dotnet-testing-advanced-aspire-testing
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。不同来源提供的安装方式可能略有差异;本站展示可直接复制的安装命令,安装前请核对来源页面。

skills.shnpx skills
npx skills add https://github.com/kevintsengtw/dotnet-testing-agent-skills --skill dotnet-testing-advanced-aspire-testing

简介

dotnet-testing-advanced-aspire-testing 专为 .NET Aspire 应用编排设计封闭式集成测试框架。

  • 使用真实容器模拟分布式架构,自动管理 AppHost 环境下的服务依赖。
  • 区别于 Testcontainers 的手动配置,提供声明式编排与一键启动能力。
  • 必须配合 AppHost 项目使用,不支持传统 WebAPI 单体结构直接接入。
  • 需预先安装 Docker Desktop 并确保 WSL2/Hyper-V 后端可用。

SKILL.md

.NET Aspire Testing 整合測試框架

前置需求

  • .NET 8 SDK 或更高版本
  • Docker Desktop(WSL 2 或 Hyper-V)
  • AppHost 專案(.NET Aspire 應用編排)

核心概念

.NET Aspire Testing 定位

.NET Aspire Testing 是封閉式整合測試框架,專為分散式應用設計:

  • 在測試中重現與正式環境相同的服務架構
  • 使用真實容器而非模擬服務
  • 自動管理容器生命週期

AppHost 專案的必要性

使用.NET Aspire Testing 必須建立 AppHost 專案:

  • 定義完整的應用架構和容器編排
  • 測試重用 AppHost 配置建立環境
  • 沒有 AppHost 就無法使用 Aspire Testing

與 Testcontainers 的差異

特性.NET Aspire TestingTestcontainers
設計目標雲原生分散式應用通用容器測試
配置方式AppHost 宣告式定義程式碼手動配置
服務編排自動處理手動管理
學習曲線較高中等
適用場景已用 Aspire 的專案傳統 Web API

專案結構

MyApp/
├── src/
│   ├── MyApp.Api/                    # WebApi 層
│   ├── MyApp.Application/            # 應用服務層
│   ├── MyApp.Domain/                 # 領域模型
│   └── MyApp.Infrastructure/         # 基礎設施層
├── MyApp.AppHost/                    # Aspire 編排專案 ⭐
│   ├── MyApp.AppHost.csproj
│   └── Program.cs
└── tests/
    └── MyApp.Tests.Integration/      # Aspire Testing 整合測試
        ├── MyApp.Tests.Integration.csproj
        ├── Infrastructure/
        │   ├── AspireAppFixture.cs
        │   ├── IntegrationTestCollection.cs
        │   ├── IntegrationTestBase.cs
        │   └── DatabaseManager.cs
        └── Controllers/
            └── MyControllerTests.cs

必要套件

AppHost 專案

<Project Sdk="Microsoft.NET.Sdk">
  <Sdk Name="Aspire.AppHost.Sdk" Version="9.0.0" />

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net9.0</TargetFramework>
    <IsAspireHost>true</IsAspireHost>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Aspire.Hosting.AppHost" Version="9.1.0" />
    <PackageReference Include="Aspire.Hosting.PostgreSQL" Version="9.1.0" />
    <PackageReference Include="Aspire.Hosting.Redis" Version="9.1.0" />
  </ItemGroup>

  <ItemGroup>
    <ProjectReference Include="..\src\MyApp.Api\MyApp.Api.csproj" />
  </ItemGroup>
</Project>

測試專案

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net9.0</TargetFramework>
    <IsTestProject>true</IsTestProject>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Aspire.Hosting.Testing" Version="13.1.3" />
    <PackageReference Include="AwesomeAssertions" Version="9.4.0" />
    <PackageReference Include="AwesomeAssertions.Web" Version="1.9.6" />
    <PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="9.0.0" />
    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.3.0" />
    <PackageReference Include="Respawn" Version="7.0.0" />
    <PackageReference Include="xunit" Version="2.9.3" />
    <PackageReference Include="xunit.runner.visualstudio" Version="3.1.5" />
  </ItemGroup>

  <ItemGroup>
    <ProjectReference Include="..\..\MyApp.AppHost\MyApp.AppHost.csproj" />
  </ItemGroup>
</Project>

容器生命週期管理

使用 ContainerLifetime.Session 確保測試資源自動清理:

var postgres = builder.AddPostgres("postgres")
                     .WithLifetime(ContainerLifetime.Session);

var redis = builder.AddRedis("redis")
                  .WithLifetime(ContainerLifetime.Session);
  • Session:測試會話結束後自動清理(推薦)
  • Persistent:容器持續運行,需手動清理

等待服務就緒

容器啟動與服務就緒是兩個階段,需要等待機制:

private async Task WaitForPostgreSqlReadyAsync()
{
    const int maxRetries = 30;
    const int delayMs = 1000;

    for (int i = 0; i < maxRetries; i++)
    {
        try
        {
            var connectionString = await GetConnectionStringAsync();
            await using var connection = new NpgsqlConnection(connectionString);
            await connection.OpenAsync();
            return;
        }
        catch (Exception ex) when (i < maxRetries - 1)
        {
            await Task.Delay(delayMs);
        }
    }
    throw new InvalidOperationException("PostgreSQL 服務未能就緒");
}

資料庫初始化

Aspire 啟動容器但不自動建立資料庫:

private async Task EnsureDatabaseExistsAsync(string connectionString)
{
    var builder = new NpgsqlConnectionStringBuilder(connectionString);
    var databaseName = builder.Database;
    builder.Database = "postgres"; // 連到預設資料庫

    await using var connection = new NpgsqlConnection(builder.ToString());
    await connection.OpenAsync();

    var checkDbQuery = $"SELECT 1 FROM pg_database WHERE datname = '{databaseName}'";
    var dbExists = await new NpgsqlCommand(checkDbQuery, connection).ExecuteScalarAsync();

    if (dbExists == null)
    {
        await new NpgsqlCommand($"CREATE DATABASE \"{databaseName}\"", connection)
            .ExecuteNonQueryAsync();
    }
}

Respawn 配置

使用 PostgreSQL 時指定適配器:

_respawner = await Respawner.CreateAsync(connection, new RespawnerOptions
{
    TablesToIgnore = new Table[] { "__EFMigrationsHistory" },
    SchemasToInclude = new[] { "public" },
    DbAdapter = DbAdapter.Postgres  // 明確指定(7.0 起可從 DbConnection 自動推斷,但建議保留)
});
Respawn 7.0 升級提示: - DbAdapter 現可從 DbConnection 型別自動推斷(使用 NpgsqlConnection 時自動選擇 Postgres),但明確指定仍建議以確保正確性 - Microsoft.Data.SqlClient 不再作為傳遞依賴;若需重置 SQL Server 需自行加入該套件 - 新增 SQLite、IBM DB2、Snowflake 適配器支援 - 新增 FormatDeleteStatement 可自訂刪除語句

Collection Fixture 最佳實踐

避免每個測試類別重複啟動容器:

[CollectionDefinition("Integration Tests")]
public class IntegrationTestCollection : ICollectionFixture<AspireAppFixture>
{
}

[Collection("Integration Tests")]
public class MyControllerTests : IntegrationTestBase
{
    public MyControllerTests(AspireAppFixture fixture) : base(fixture) { }
}

時間可測試性

使用 TimeProvider 抽象化時間依賴:

// 服務實作
public class ProductService
{
    private readonly TimeProvider _timeProvider;

    public ProductService(TimeProvider timeProvider)
    {
        _timeProvider = timeProvider;
    }

    public async Task<Product> CreateAsync(ProductCreateRequest request)
    {
        var now = _timeProvider.GetUtcNow();
        var product = new Product
        {
            CreatedAt = now,
            UpdatedAt = now
        };
        // ...
    }
}

// DI 註冊
builder.Services.AddSingleton<TimeProvider>(TimeProvider.System);

選擇建議

選擇.NET Aspire Testing

  • 專案已使用.NET Aspire
  • 需要測試多服務互動
  • 重視統一的開發測試體驗
  • 雲原生應用架構

選擇 Testcontainers

  • 傳統.NET 專案
  • 需要精細的容器控制
  • 與非.NET 服務整合
  • 團隊對 Aspire 不熟悉

常見問題

端點配置衝突

不要手動配置已由 Aspire 自動處理的端點:

// ❌ 錯誤:會造成衝突
builder.AddProject<Projects.MyApp_Api>("my-api")
       .WithHttpEndpoint(port: 8080, name: "http");

// ✅ 正確:讓 Aspire 自動處理
builder.AddProject<Projects.MyApp_Api>("my-api")
       .WithReference(postgresDb)
       .WithReference(redis);

Dapper 欄位映射

PostgreSQL snake_case 與 C# PascalCase 的映射:

// 在 Program.cs 初始化
DapperTypeMapping.Initialize();

// 或使用 SQL 別名
const string sql = @"
    SELECT id, name, price,
           created_at AS CreatedAt,
           updated_at AS UpdatedAt
    FROM products";

輸出格式

  • 產生 AppHost 專案的 Program.cs,定義容器編排與服務參考
  • 產生測試基礎設施檔案:AspireAppFixture.csIntegrationTestCollection.csIntegrationTestBase.cs
  • 產生 DatabaseManager.cs 處理資料庫初始化與 Respawn 清理
  • 產生控制器測試類別(*ControllerTests.cs),繼承 IntegrationTestBase
  • 修改測試專案 .csproj,加入 Aspire.Hosting.Testing 與相關套件參考

參考資源

原始文章

本技能內容提煉自「老派軟體工程師的測試修練 - 30 天挑戰」系列文章:

  • Day 24 -.NET Aspire Testing 入門基礎介紹

- 鐵人賽文章:https://ithelp.ithome.com.tw/articles/10377071 - 範例程式碼:https://github.com/kevintsengtw/30Days_in_Testing_Samples/tree/main/day24

  • Day 25 -.NET Aspire 整合測試實戰:從 Testcontainers 到.NET Aspire Testing

- 鐵人賽文章:https://ithelp.ithome.com.tw/articles/10377197 - 範例程式碼:https://github.com/kevintsengtw/30Days_in_Testing_Samples/tree/main/day25

官方文件

範例檔案

請參考同目錄下的範例檔案:

  • templates/apphost-program.cs - AppHost 編排定義
  • templates/aspire-app-fixture.cs - 測試基礎設施
  • templates/integration-test-collection.cs - Collection Fixture 設定
  • templates/integration-test-base.cs - 測試基底類別
  • templates/database-manager.cs - 資料庫管理員
  • templates/controller-tests.cs - 控制器測試範例
  • templates/test-project.csproj - 測試專案設定
  • templates/apphost-project.csproj - AppHost 專案設定

相關技能

  • dotnet-testing-advanced-testcontainers-database - Testcontainers 資料庫測試
  • dotnet-testing-advanced-testcontainers-nosql - Testcontainers NoSQL 測試
  • dotnet-testing-advanced-webapi-integration-testing - 完整 WebAPI 整合測試

适合场景

01

用户想查找某类 Agent Skill 时

02

需要根据任务场景推荐可安装能力包时

03

需要对比不同来源的安装命令和来源信息时

04

需要参考平台分布和安装热度时

能力概览

能力 1

按任务关键词查找相关 Skills

能力 2

展示可复制的安装命令

能力 3

保留来源站点、仓库和原始说明,方便继续核验

能力 4

补充不同宿主或平台的使用分布数据

能力 5

展示第三方安全扫描或审计结果

安装后应在对应宿主中按原始 README 的触发条件使用;具体调用方式请以来源页面和 README 为准。

平台分布

Gemini CLI

26.59%
按下载量换算56

Antigravity

20.06%
按下载量换算43

Claude Code

16.84%
按下载量换算36

OpenCode

13.75%
按下载量换算29

trae

7.76%
按下载量换算16

Cursor

3.54%
按下载量换算8

安全审计

Gen Agent Trust Hub

通过

Socket

通过

Snyk

通过

权限和风险

需要联网

该 Skill 可能需要联网访问来源站点、仓库或外部 API;具体网络访问范围需要结合源码和 README 复核。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。

来源信息

继续浏览同类 Skills