SuperAPI AI 工具集

eaf-testing

测试与质量

查看项目

更新于 10-15 10:10

技能介绍

用途

EAF Testing 是一份用于测试 EAF(Enterprise Application Foundation)模块的技能指南。EAF 是构建在 ASP.NET Boilerplate(ABP)之上的开源中间件平台,测试对于保障代码质量、维持各模块约 90% 的覆盖率至关重要。该技能面向使用 xUnit、Shouldly 断言与 NSubstitute 模拟编写功能完整、可维护测试的开发者。

技术栈

  • .NET 版本:10.0
  • 测试框架:xUnit 2.4+
  • 断言库:Shouldly 4.x
  • 模拟库:NSubstitute 5.x
  • 覆盖率:coverlet.collector 6.x
  • ABP 测试:Abp.TestBase、Abp.EntityFramework.TestBase

测试项目结构

test/
├── Eaf.ModuleName.Tests/
│   ├── EafModuleNameTestModule.cs
│   ├── ModuleName/
│   │   ├── EntityName_Tests.cs
│   │   └── ServiceName_Tests.cs
│   └── Eaf.ModuleName.Tests.csproj

测试基类与测试模块

集成测试基类继承 AbpIntegratedTestBase<EafMyModuleTestModule>,可重写 PreInitialize 与 PostInitialize。测试模块通过 [DependsOn(typeof(EafMyModule), typeof(AbpTestBaseModule))] 声明依赖,并在 Initialize 中调用 IocManager.RegisterAssemblyByConvention 与 ServiceCollectionRegistrar.Register。

BDD 命名模式(葡萄牙语)

测试命名采用 BDD 模式:Dado_ParametroValido_Quando_ChamarMetodo_Entao_DeveRetornarSucesso,对应 Given/When/Then 三段结构。

主要测试类型

  • 实体测试:验证实体创建与校验,例如无效邮箱应抛出 AbpValidationException。
  • 应用服务测试:通过 Resolve<IUserAppService>() 解析服务,测试创建用户等场景。
  • 带模拟的服务测试:使用 Substitute.For<IRepository<User, Guid>>() 构造模拟仓储,并用 Received(1) 验证调用。
  • 仓储测试:解析自定义仓储(如 IUserRepository)并测试按邮箱查询等方法。
  • 中间件模块测试:如 KeyVault 模块的 IEafKeyVaultManager.GetSecretAsync、OpenTelemetry 模块的配置检查。

覆盖率

运行测试并收集覆盖率:

dotnet test --collect:"XPlat Code Coverage"

coverlet.runsettings 配置示例:

<?xml version="1.0" encoding="utf-8" ?>
<RunSettings>
  <DataCollectionRunSettings>
    <DataCollectors>
      <DataCollector friendlyName="XPlat Code Coverage">
        <Configuration>
          <Format>opencover,cobertura</Format>
          <Exclude>[Eaf.*Tests]*,[*.Module]*</Exclude>
        </Configuration>
      </DataCollector>
    </DataCollectors>
  </DataCollectionRunSettings>
</RunSettings>

常见测试模式

  • Arrange-Act-Assert 模式。
  • 异步方法测试(async Task + await)。
  • 异常测试:Should.Throw<ArgumentException> 与 await Should.ThrowAsync<ArgumentException>。
  • 数据驱动测试:[Theory] 配合 [InlineData]。

Shouldly 常用断言

相等(ShouldBe/ShouldNotBe)、空值检查(ShouldNotBeNull/ShouldBeNull)、布尔(ShouldBeTrue/ShouldBeFalse)、集合(Count.ShouldBe、ShouldContain/ShouldNotContain)、异常(Should.Throw<Exception>)。

NSubstitute 常用写法

设置返回值:_repository.GetAsync(id).Returns(user)、_repository.GetAll().Returns(users.AsQueryable())。验证调用:await _repository.Received(1).GetAsync(id)、_repository.DidNotReceive().Delete(id)。参数匹配:Arg.Any<Guid>()、Arg.Is<Guid>(x => x != Guid.Empty)。

最佳实践

  • 命名采用葡萄牙语 BDD 模式 Dado_Quando_Entao,描述被测场景。
  • 测试相互独立,不依赖执行顺序,每个测试后清理。
  • 保持测试简单聚焦,变量命名具描述性,尽量每个测试一个断言。
  • 对外部依赖使用模拟,避免慢操作,尽可能并行运行。
  • 同时测试成功与失败场景,目标覆盖率大于 90%,提交前运行测试。

常见问题与解决

  • 测试初始化:在构造函数中解析依赖。
  • 数据库上下文:在 PreInitialize 中调用 UseInMemoryDatabase()。
  • 权限问题:在 PostInitialize 中通过 UsingDbContext 添加 PermissionGrant。

适用场景与限制

适用于使用 EAF/ABP 框架、以 .NET 10 与 xUnit 技术栈编写模块测试的开发者。资料未提供该技能的安装命令、收费方式、平台限制或具体版本兼容性说明,这些信息暂未提供。