关于 aspire-integration-testing
为 .NET Aspire 应用提供 xUnit 集成测试指导,适用于需要验证真实基础设施和服务间通信的团队。内容强调动态端口、运行时端点发现、健康检查及异步夹具生命周期,也涵盖 Aspire MCP 调试集成。
主要功能
- 01使用 Aspire 编排真实依赖
- 02xUnit 异步夹具生命周期管理
- 03动态端口与运行时端点发现
- 04健康检查与并行隔离
- 05数据库、消息队列和 UI 测试模式
- 06通过 Aspire MCP 查看运行状态与遥测
适用场景
- 01测试连接真实数据库的 ASP.NET Core 应用
- 02验证微服务之间的通信
- 03使用容器化基础设施测试消息队列
- 04结合 Playwright 和 Aspire 服务测试 UI
MCP 相关
文档介绍 Aspire CLI 的 MCP 集成,供 AI 助手查询资源状态、端点、健康状况、日志和分布式追踪,也可执行资源命令并发现集成。
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ wshaddix/ dotnet-skills --skill aspire-integration-testing安装后在 Claude Code 中输入/aspire-integration-testing确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
reference/configuration-examples.mdtest-fixtures.mdtesting-patterns.md详细介绍
使用 .NET Aspire + xUnit 进行集成测试
何时使用此技能
在以下情况下使用此技能:
- 为 .NET Aspire 应用编写集成测试
- 使用真实数据库连接测试 ASP.NET Core 应用
- 验证分布式应用中的服务间通信
- 在容器中使用实际基础设施(SQL Server、Redis、消息队列)进行测试
- 将 Playwright UI 测试与 Aspire 编排的服务结合使用
- 使用适当的服务发现和网络配置测试微服务
核心原则
- 真实依赖项 - 通过 Aspire 使用实际基础设施(数据库、缓存),而非模拟对象
- 动态端口绑定 - 让 Aspire 动态分配端口(
127.0.0.1:0),以避免冲突 - Fixture 生命周期 - 使用
IAsyncLifetime正确设置和清理测试 Fixture - 端点发现 - 切勿硬编码 URL;应在运行时从 Aspire 发现端点
- 并行隔离 - 使用 xUnit 集合控制测试并行化
- 运行状况检查 - 运行测试前,务必等待服务达到健康状态
高层测试架构
┌─────────────────┐ ┌──────────────────────┐
│ xUnit test file │──uses────────────►│ AspireFixture │
└─────────────────┘ │ (IAsyncLifetime) │
└──────────────────────┘
│
│ starts
▼
┌───────────────────────────┐
│ DistributedApplication │
│ (from AppHost) │
└───────────────────────────┘
│ exposes
▼
┌──────────────────────────────┐
│ Dynamic HTTP Endpoints │
└──────────────────────────────┘
│ consumed by
▼
┌─────────────────────────┐
│ 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()
{
// Disable config file watching in test hosts
// Prevents file descriptor exhaustion (inotify watch limit) on Linux
Environment.SetEnvironmentVariable("DOTNET_HOSTBUILDER__RELOADCONFIGONCHANGE", "false");
}
}
原因: [ModuleInitializer] 会在任何测试代码执行前运行,为测试期间创建的所有 IHost 实例全局设置环境变量。
参考文档
有关详细模式和示例,请参阅以下参考文件:
- 测试 Fixture - xUnit 测试 Fixture、测试类组织、Fixture 生命周期模式和数据库重置策略
- 测试模式 - 测试单个服务、服务间通信、真实数据库、消息代理和 Playwright UI 测试
- 配置示例 - 资源配置、环境变量配置和等待策略
常见模式摘要
| 模式 | 使用场景 |
|---|---|
| 基本 Fixture | 简单的 HTTP 端点测试 |
| 端点发现 | 避免硬编码 URL |
| 数据库测试 | 验证数据访问层 |
| Playwright 集成 | 使用真实后端进行完整 UI 测试 |
| 配置覆盖 | 特定于测试的设置 |
| 运行状况检查 | 确保服务已就绪 |
| 服务通信 | 测试分布式系统交互 |
| 消息队列测试 | 验证异步消息传递 |
棘手/不明显的提示
| 问题 | 解决方案 |
|---|---|
| 测试立即超时 | 调用 await _app.StartAsync(),并在运行测试前等待服务达到健康状态 |
| 测试之间发生端口冲突 | 使用 xUnit CollectionDefinition 共享 Fixture,避免启动多个实例 |
| 因时序导致测试不稳定 | 实施适当的运行状况检查轮询,而不是使用 Task.Delay() |
| 无法连接 SQL Server | 确保通过 GetConnectionStringAsync() 动态获取连接字符串 |
| 并行测试互相干扰 | 使用 [Collection] 特性按顺序运行相关测试 |
| Aspire 仪表板冲突 | 同一时间只能运行一个 Aspire 仪表板;测试会复用同一个仪表板实例 |
CI/CD 集成
GitHub Actions 示例
name: Integration Tests
on:
push:
branches: [ main, dev ]
pull_request:
branches: [ main, dev ]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup .NET
uses: actions/setup-dotnet@v3
with:
dotnet-version: 9.0.x
- name: Restore dependencies
run: dotnet restore
- name: Build
run: dotnet build --no-restore -c Release
- name: Run integration tests
run: |
dotnet test tests/YourApp.IntegrationTests \
--no-build \
-c Release \
--logger trx \
--collect:"XPlat Code Coverage"
- name: Publish test results
uses: actions/upload-artifact@v3
if: always()
with:
name: test-results
path: "**/TestResults/*.trx"
最佳实践
- 使用
IAsyncLifetime- 确保正确进行异步初始化和清理 - 通过集合共享固定装置 - 通过重用应用实例缩短测试执行时间
- 动态发现端点 - 切勿硬编码 localhost:5000 或类似地址
- 等待健康检查 - 不要假设服务会立即就绪
- 使用真实依赖项进行测试 - Aspire 让使用真实的 SQL、Redis 等变得轻松
- 清理资源 - 始终正确实现
DisposeAsync - 使用有意义的测试数据 - 使用真实的测试数据填充数据库
- 测试失败场景 - 验证错误处理和弹性
- 保持测试隔离 - 每项测试都应独立,且不依赖执行顺序
- 监控测试执行时间 - 如果测试运行缓慢,可考虑并行化或优化
Aspire CLI 和 MCP 集成
Aspire 13.1+ 集成了 MCP(Model Context Protocol),可供 Claude Code 等 AI 编码助手使用。AI 工具可以查询应用状态、查看日志和检查跟踪记录。
安装 Aspire CLI
# Install the Aspire CLI globally
dotnet tool install -g aspire.cli
# Or update existing installation
dotnet tool update -g aspire.cli
为 Claude Code 初始化 MCP
# Navigate to your Aspire project
cd src/MyApp.AppHost
# Initialize MCP configuration (auto-detects Claude Code)
aspire mcp init
这会创建必要的配置文件,以便 Claude Code 连接到正在运行的 Aspire 应用。
启用 MCP 后运行
# Run your Aspire app with MCP server
aspire run
# The CLI will output the MCP endpoint URL
# Claude Code can then connect and query:
# - Resource states and health status
# - Real-time console logs
# - Distributed traces
# - Available Aspire integrations
MCP 功能
连接后,AI 助手可以:
- 查询资源 - 获取资源状态、端点和健康状态
- 通过日志调试 - 访问所有服务的实时控制台输出
- 调查遥测数据 - 查看结构化日志和分布式跟踪记录
- 执行命令 - 运行特定于资源的命令
- 发现集成 - 列出可用的 Aspire 托管集成(Redis、PostgreSQL、Azure 服务)
对开发的益处
- AI 助手可以查看实际运行的应用状态
- 调试辅助会使用真实的遥测数据
- 无需手动复制/粘贴日志
- AI 可以帮助关联分布式跟踪中的跨度
更多详情请参阅:
调试技巧
- 运行 Aspire Dashboard - 测试失败时,检查
http://localhost:15888上的控制面板 - 将 Aspire CLI 与 MCP 配合使用 - 让 AI 助手查询实际应用状态
- 启用详细日志记录 - 设置
ASPIRE_ALLOW_UNSECURED_TRANSPORT=true以获得更详细的输出 - 检查容器日志 - 使用
docker logs检查容器输出 - 在固定装置中使用断点 - 调试固定装置初始化,以发现启动问题
- 验证资源名称 - 确保 AppHost 和测试中的资源名称一致
评论
支持 Markdown