关于 mcp-csharp-test
用于测试 C# MCP 服务的技能,涵盖工具方法的单元测试和通过 MCP 协议进行的集成测试,也介绍 LLM 评估与 CI 测试设置。
主要功能
- 01对单个工具方法进行单元测试
- 02模拟工具依赖
- 03测试 MCP 工具列表与调用
- 04运行筛选测试和覆盖率检查
- 05设计只读 LLM 评估
适用场景
- 01为服务添加自动化测试
- 02通过模拟验证工具行为
- 03验证协议层面的工具调用
- 04设置 CI 测试
MCP 相关
介绍使用 MCP 客户端进行集成测试,包括验证工具列表以及通过协议调用工具。
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ dotnet/ skills --skill mcp-csharp-test安装后在 Claude Code 中输入/mcp-csharp-test确认已加载。
附带文件references/evaluations.mdreferences/test-patterns.md
详细介绍
C# MCP 服务测试
在两个层面测试 MCP 服务:针对单个工具方法的单元测试,以及在内存中通过完整 MCP 协议运行的集成测试。
适用场景
- 为 MCP 服务添加自动化测试
- 使用模拟依赖项测试单个工具方法
- 编写通过 MCP 协议验证工具列表和调用的集成测试
- 为 MCP 服务设置 CI 测试流水线
停止信号
- 还没有服务? → 请先使用
mcp-csharp-create
输入
| 输入 | 必填 | 描述 |
|---|---|---|
| MCP 服务项目路径 | 是 | 被测服务 .csproj 的路径 |
| 测试框架 | 推荐 | 默认:xUnit。也支持 NUnit 或 MSTest |
| 传输类型 | 推荐 | 决定集成测试方法(stdio 或 HTTP) |
工作流
步骤 1:创建测试项目
dotnet new xunit -n <ServerName>.Tests
cd <ServerName>.Tests
dotnet add reference ../<ServerName>/<ServerName>.csproj
dotnet add package ModelContextProtocol
dotnet add package Moq
dotnet add package FluentAssertions
步骤 2:为工具方法编写单元测试
直接测试工具方法——速度最快,隔离性也最好:
public class MyToolTests
{
[Fact]
public void Echo_ReturnsFormattedMessage()
{
var result = MyTools.Echo("Hello");
result.Should().Be("Echo: Hello");
}
[Theory]
[InlineData("")]
[InlineData(" ")]
public void Echo_HandlesEdgeCases(string input)
{
var result = MyTools.Echo(input);
result.Should().StartWith("Echo:");
}
}
对于具有 DI 依赖项的工具,模拟该依赖项:
public class ApiToolTests
{
[Fact]
public async Task FetchData_ReturnsApiResponse()
{
var handler = new MockHttpMessageHandler("""{"id": 1}""");
var httpClient = new HttpClient(handler);
var result = await ApiTools.FetchData(httpClient, "resource-1");
result.Should().Contain("id");
}
}
步骤 3:使用 MCP 客户端编写集成测试
通过客户端与服务端连接测试完整 MCP 协议:
using ModelContextProtocol.Client;
public class ServerIntegrationTests : IAsyncLifetime
{
private McpClient _client = null!;
public async Task InitializeAsync()
{
var transport = new StdioClientTransport(new StdioClientTransportOptions
{
Name = "TestClient",
Command = "dotnet",
Arguments = ["run", "--project", "../<ServerName>/<ServerName>.csproj"]
});
_client = await McpClient.CreateAsync(transport);
}
public async Task DisposeAsync() => await _client.DisposeAsync();
[Fact]
public async Task Server_ListsExpectedTools()
{
var tools = await _client.ListToolsAsync();
tools.Should().Contain(t => t.Name == "echo");
}
[Fact]
public async Task Tool_ReturnsExpectedResult()
{
var result = await _client.CallToolAsync("echo",
new Dictionary<string, object?> { ["message"] = "Test" });
var text = result.Content.OfType<TextContentBlock>().First().Text;
text.Should().Contain("Test");
}
}
有关 SDK 的 ClientServerTestBase(内存测试)以及使用 WebApplicationFactory 进行 HTTP 测试,请参阅 references/test-patterns.md。
步骤 4:运行测试
# Run all tests
dotnet test
# Run a specific test class
dotnet test --filter "FullyQualifiedName~MyToolTests"
# Run with coverage
dotnet test --collect:"XPlat Code Coverage"
步骤 5:编写评估
评估用于衡量大模型使用你的工具的效果。好的评估问题应当:
- 只读且无破坏性——绝不产生副作用或修改数据
- 确定性——只有一个可验证的正确答案
- 需要多步操作——要求大模型调用多个工具,或根据结果进行推理
有关评估格式、示例问题和详细指南,请参阅 references/evaluations.md。
验证
- 单元测试覆盖所有工具方法,包括边界情况
- 集成测试通过
ListToolsAsync()验证工具列表 - 集成测试通过
CallToolAsync()验证工具调用 - 所有测试均通过:
dotnet test - 测试无需手动设置即可在 CI 中运行
常见问题
| 问题 | 解决方案 |
|---|---|
集成测试在 CreateAsync 处挂起 | 服务启动失败。先确认 dotnet build 成功。对于 stdio,确保没有向 stdout 输出日志 |
StdioClientTransport 找不到项目 | 使用相对于测试项目目录的正确 .csproj 路径 |
| 测试在本地通过,但在 CI 中失败 | 在执行测试前运行 dotnet build。仅在明确执行构建步骤后使用 --no-build |
模拟 HttpClient 很麻烦 | 模拟 HttpMessageHandler,不要直接模拟 HttpClient。请参阅 references/test-patterns.md |
| 运行完整测试套件很慢 | 开发时使用 --filter。仅在 CI 验证时运行完整套件 |
相关技能
mcp-csharp-create— 创建新的 MCP 服务项目mcp-csharp-publish— NuGet、Docker、Azure 部署
参考文件
- references/test-patterns.md — 完整测试代码示例:
ClientServerTestBase内存测试模式、用于 HTTP 的WebApplicationFactory、MockHttpMessageHandler辅助工具、测试分类、覆盖率报告。**在以下情况下加载:**编写集成测试或需要详细的模拟模式。 - references/evaluations.md — 评估格式、问题设计原则和评估问题示例。**在以下情况下加载:**用户询问评估、评估问题或工具质量衡量方式。
更多信息
- xUnit 文档 — .NET 的 xUnit 入门指南
评论
支持 Markdown