架构健康测试技能Skill fitness-functions

此技能用于通过自动化测试验证 .NET 软件架构的健康状况,帮助执行架构边界、测试模块依赖关系、验证层约束、创建性能健康函数、生成架构测试代码和审计现有架构违规。它使用 NetArchTest 和 ArchUnitNET 工具,适用于维护和演进软件架构。关键词:架构测试,健康函数,NetArchTest,ArchUnitNET,依赖规则,性能测试,代码生成,CI/CD 集成。

测试 0 次安装 0 次浏览 更新于 3/11/2026

名称: 架构健康函数 描述: 使用 NetArchTest 和 ArchUnitNET 的 .NET 架构测试指南。适用于执行架构边界、测试模块依赖关系、验证层约束或创建性能健康函数。包括代码生成模板。 参数提示: [范围] [–生成] [–框架 netarchtest|archunitnet] 允许工具: 读取, 写入, 全局, 搜索, 脚本, 技能, 任务

健康函数

何时使用此技能

在需要时使用此技能:

  • 强制模块之间的架构边界
  • 测试依赖关系是否遵循规定规则
  • 验证层约束(例如,UI → 域不应依赖)
  • 创建性能健康函数
  • 生成架构测试代码
  • 审计现有架构的违规

关键词: 健康函数,架构测试,NetArchTest,ArchUnitNET,依赖规则,层约束,架构边界,模块隔离,架构验证,性能测试

什么是健康函数?

健康函数是验证架构特征的自动化测试。它们提供客观、可重复的验证,以确保系统在演进过程中保持期望的属性。

健康函数类型

类型 验证内容 示例
依赖 组件关系 “域不能依赖基础设施”
垂直切片规则 “控制器仅调用应用层”
命名 约定合规性 “处理程序必须以’Handler’结尾”
性能 运行时特征 “API响应在p95时小于200毫秒”
循环复杂度 代码复杂度 “无方法循环复杂度大于10”

快速开始

1. 安装所需包

# 对于 NetArchTest(更简单,推荐大多数情况)
dotnet add package NetArchTest.Rules

# 对于 ArchUnitNET(更强大,Java类语法)
dotnet add package ArchUnitNET
dotnet add package ArchUnitNET.xUnit  # 或 .NUnit

2. 创建测试项目

dotnet new xunit -n YourSolution.ArchitectureTests
dotnet add YourSolution.ArchitectureTests reference src/YourSolution.Domain
dotnet add YourSolution.ArchitectureTests reference src/YourSolution.Application
dotnet add YourSolution.ArchitectureTests reference src/YourSolution.Infrastructure

3. 编写第一个测试

public class DependencyTests
{
    [Fact]
    public void Domain_ShouldNotDependOn_Infrastructure()
    {
        var result = Types.InAssembly(typeof(Order).Assembly)
            .ShouldNot()
            .HaveDependencyOn("YourSolution.Infrastructure")
            .GetResult();

        Assert.True(result.IsSuccessful, result.FailingTypeNames?.FirstOrDefault());
    }
}

NetArchTest 模式

NetArchTest 提供了测试架构约束的流畅API。

详细模式:references/netarchtest-patterns.md

常见规则

// 依赖约束
Types.InAssembly(domainAssembly)
    .ShouldNot()
    .HaveDependencyOn("Microsoft.EntityFrameworkCore");

// 命名约定
Types.InAssembly(applicationAssembly)
    .That()
    .ImplementInterface(typeof(IRequestHandler<,>))
    .Should()
    .HaveNameEndingWith("Handler");

// 层隔离
Types.InNamespace("Domain")
    .ShouldNot()
    .HaveDependencyOnAny("Application", "Infrastructure", "Api");

ArchUnitNET 模式

ArchUnitNET 提供更表达性的规则,语法类似于Java的ArchUnit。

详细模式:references/archunitnet-patterns.md

常见规则

// 定义架构层
private static readonly Architecture Architecture =
    new ArchLoader().LoadAssemblies(
        typeof(Order).Assembly,
        typeof(OrderHandler).Assembly,
        typeof(OrderRepository).Assembly
    ).Build();

private static readonly IObjectProvider<IType> DomainLayer =
    Types().That().ResideInNamespace("Domain").As("域层");

private static readonly IObjectProvider<IType> InfrastructureLayer =
    Types().That().ResideInNamespace("Infrastructure").As("基础设施层");

[Fact]
public void DomainLayer_ShouldNotDependOn_InfrastructureLayer()
{
    IArchRule rule = Types().That().Are(DomainLayer)
        .Should().NotDependOnAny(InfrastructureLayer);

    rule.Check(Architecture);
}

依赖规则目录

模块化单体应用的常见依赖规则:

完整目录:references/dependency-rules.md

模块隔离

[Fact]
public void Modules_ShouldNotCrossReference_CoreProjects()
{
    var orderingCore = Types.InAssembly(typeof(Order).Assembly);
    var inventoryCore = Types.InAssembly(typeof(Product).Assembly);

    // Ordering.Core 不能引用 Inventory.Core
    var result = orderingCore
        .ShouldNot()
        .HaveDependencyOn("Inventory.Core")
        .GetResult();

    Assert.True(result.IsSuccessful);
}

共享内核约束

[Fact]
public void SharedKernel_ShouldNotDependOn_AnyModule()
{
    var sharedKernel = Types.InAssembly(typeof(Entity).Assembly);

    var result = sharedKernel
        .ShouldNot()
        .HaveDependencyOnAny(
            "Ordering", "Inventory", "Shipping", "Customers")
        .GetResult();

    Assert.True(result.IsSuccessful);
}

性能健康函数

测试运行时特征以确保性能标准。

详细指南:references/performance-fitness.md

响应时间测试

[Fact]
public async Task Api_ShouldRespondWithin_200ms()
{
    var client = _factory.CreateClient();
    var stopwatch = Stopwatch.StartNew();

    var response = await client.GetAsync("/api/orders/123");

    stopwatch.Stop();
    Assert.True(stopwatch.ElapsedMilliseconds < 200,
        $"响应耗时 {stopwatch.ElapsedMilliseconds} 毫秒");
}

内存分配测试

[Fact]
public void Handler_ShouldNotAllocateExcessiveMemory()
{
    var before = GC.GetTotalMemory(true);

    for (int i = 0; i < 1000; i++)
    {
        _handler.Handle(new GetOrderQuery(Guid.NewGuid()));
    }

    var after = GC.GetTotalMemory(true);
    var allocated = (after - before) / 1000;  // 每次操作

    Assert.True(allocated < 10_000, $"每次操作分配 {allocated} 字节");
}

代码生成模板

使用这些模板快速创建架构测试:

  • references/templates/architecture-test-template.cs - 完整测试类脚手架
  • references/templates/performance-test-template.cs - 性能测试模式

快速模板使用

# 复制模板并定制化
cp templates/architecture-test-template.cs tests/ArchitectureTests.cs

与 CI/CD 集成

GitHub Actions 示例

- name: 运行架构测试
  run: dotnet test --filter Category=Architecture
  continue-on-error: false  # 违规时使流水线失败

测试类别

[Trait("Category", "Architecture")]
public class DependencyTests
{
    // 架构测试与单元测试分开运行
}

与事件风暴集成

健康函数强制执行通过事件风暴发现的边界:

事件风暴 → 有界上下文
    ↓
模块化架构 → 模块结构
    ↓
健康函数 → 强制执行边界

事件风暴识别有界上下文后:

  1. 基于上下文定义模块
  2. 创建模块间依赖规则
  3. 添加健康函数以强制执行隔离

最佳实践

  1. 在 CI/CD 中运行 - 合并前捕获违规
  2. 从关键规则开始 - 不要一开始就测试所有内容
  3. 清晰的失败消息 - 使违规易于理解
  4. 分类测试 - 与单元/集成测试分开
  5. 记录意图 - 解释每个规则存在的原因
  6. 定期审查 - 随架构演进更新规则

故障排除

常见问题

测试未找到类型:

  • 检查测试项目中的程序集引用
  • 验证命名空间模式与实际命名空间匹配

误报:

  • 为合法依赖添加排除
  • 检查通过共享包的间接依赖

性能测试不稳定:

  • 测量前使用预热运行
  • 在隔离环境中运行
  • 使用统计显著性(多次运行)

参考资料

  • references/netarchtest-patterns.md - NetArchTest 使用模式
  • references/archunitnet-patterns.md - ArchUnitNET 使用模式
  • references/performance-fitness.md - 性能测试模式
  • references/dependency-rules.md - 常见依赖规则目录
  • references/templates/architecture-test-template.cs - 测试类模板
  • references/templates/performance-test-template.cs - 性能测试模板

用户界面

当用户直接调用时,此技能分析架构健康并可选生成测试。

执行工作流

  1. 解析参数 - 提取范围(默认:当前目录)、--生成 标志和 --框架 偏好(netarchtest 或 archunitnet)。
  2. 分析项目结构 - 发现解决方案/项目文件、命名空间层次结构、架构风格(清洁、六边形、模块化单体、垂直切片)和类型约定。
  3. 评估健康 - 检查依赖规则(域不依赖基础设施)、层约束(控制器仅在表示层)和命名约定(处理程序以"Handler"结尾)。
  4. 生成报告 - 生成健康报告,包括摘要表、通过/失败检查、违规位置和优先级建议。
  5. 生成测试(如果 --generate) - 生成健康函数生成器代理以创建包含 DependencyTests、NamingConventionTests 和 StructureTests 的测试项目。
  6. 建议 CI/CD 集成 - 推荐将架构测试添加到 GitHub Actions 工作流。

版本历史

  • v1.0.0 (2025-12-22):初始发布
    • NetArchTest 和 ArchUnitNET 模式
    • 依赖规则目录
    • 性能健康函数
    • 代码生成模板
    • CI/CD 集成指南

最后更新

日期: 2025-12-22 模型: claude-opus-4-5-20251101