Skip to content

opt: 提升单元测试覆盖率至 85%,补充 AI/Domain/EFCore/Logging 核心分支测试#32

Merged
MarsonShine merged 1 commit into
refactor/framework-optimization-from-reviewfrom
marsonshine-optimize-test-coverage
Jun 29, 2026
Merged

opt: 提升单元测试覆盖率至 85%,补充 AI/Domain/EFCore/Logging 核心分支测试#32
MarsonShine merged 1 commit into
refactor/framework-optimization-from-reviewfrom
marsonshine-optimize-test-coverage

Conversation

@MarsonShine

Copy link
Copy Markdown
Owner

动机

本轮优化前有效行覆盖率为 81.42%,分支覆盖率为 68.93%。核心代码区域(AI Provider、领域事件溯源、EFCore 查询扩展、Logging Provider)存在大量未覆盖的业务分支和异常路径,直接影响了 CI 质量门禁的可靠性。

改动内容

新增:覆盖策略与基础设施

  • 添加 coverlet.runsettings,定义有效覆盖范围:
    • 排除 DTO/Request/Response/Options 纯数据容器
    • 排除生成代码、bin/obj、Migrations
    • 跳过自动属性
  • 安装 dotnet-reportgenerator-globaltool 作为本地工具

新增:高收益测试(751 行新增)

目标区域 覆盖要点
DefaultAIModelResolver 显式 model 回退默认 provider、provider override 缺 model、大小写不敏感匹配、provider 无法确定/未配置分支
AI Production 组件 限流器/熔断器/日志脱敏器/SecretProvider/PayloadLimit 的成功与失败边界
OpenAI Provider 校验 disabled/missing api key/invalid uri 聚合式验证
OpenAIMedia/TTS Provider content-type 映射、content safety 异常、429 retry-after、503 重试成功、超时异常
OrderAggregate 事件溯源 重复加购累计价格、移除商品、重复创建冲突、已取消冲突、remove 非法数量
EFCore ApplySpecification criteria-only、排序链+分页、投影成功、缺 selector 异常
NLog/Serilog HostBuilder 重载 验证 IHostBuilder.ConfigureMsXxx 重载能正确注册和输出日志

删除/重写:无意义测试(54 行删除)

  • 删除 3 个纯 DTO 属性 get/set 的测试(MsPlatformDbContextSettingsTests
  • 重写 1 个仅断言 NotNull 的测试为行为验证(MsNLogProviderTests.ConfigLoad

结果

  • 行覆盖率: 81.42% -> 85.28%
  • 分支覆盖率: 68.93% -> 75.99%
  • 测试通过: 1086 通过,0 失败,19 skip(性能基线)
  • 关键 Assembly 提升:
    • MS.Microservice.AI.Abstractions: 67.61% -> 100%
    • MS.Microservice.AI.Core: 83.24% -> 89.60%
    • MS.Microservice.Domain: 78.96% -> 81.82%
    • MS.Microservice.Logging.NLog: 66.67% -> 85.00%
    • MS.Microservice.Logging.Serilog: 76.56% -> 85.94%
    • MS.Microservice.Persistence.EFCore: 74.29% -> 86.94%(分支从 29% 提升至 74%)

值得关注的设计决策

  • coverlet.runsettings 移到了解决方案根目录,原 test/coverlet.runsettings 路径导致只有 Core.Tests 项目能识别;新位置对所有测试项目生效
  • AI Provider 校验测试 使用真实 IServiceCollection 注册 + 断言异常 ValidationException 聚合消息,而不是 mock IServiceProvider,这样同时覆盖了 ProviderRegistrationValidation 的完整路径
  • 本轮未覆盖 SqlSugarQueryableExtensions(强依赖 Sugar provider 语义)、Swagger ApplicationBuilderExtensions(HTTP pipeline 级,单测成本高于收益)、RsaCrypt 剩余 ASN.1 分支(需畸形 DER/PKCS8 样本),均已记录;后续可根据实际缺陷率决定是否补

- 新增 AI 模型解析器测试:显式/回退/大小写/缺省场景
- 新增 AI 生产就绪组件测试:限流、熔断、日志脱敏、SecretProvider、PayloadLimit
- 新增 OpenAI Provider 校验测试:disabled/missing key/invalid uri
- 新增 OpenAIMedia/TTS Provider 测试:content-type、content safety、retry、timeout
- 新增 OrderAggregate 决策与状态演进测试:重复操作、冲突、非法的 boundary
- 新增 EFCore ApplySpecification 测试:criteria-only、排序链、分页、投影
- 新增 NLog/Serilog HostBuilder 重载测试
- 新增 coverlet.runsettings 排除规则:DTO/Options/自动属性/生成代码
- 删除 3 个纯 get/set 无意义测试
- 重写 1 个弱断言测试为行为验证
Copilot AI review requested due to automatic review settings June 29, 2026 01:58
@MarsonShine MarsonShine merged commit c78cc4d into refactor/framework-optimization-from-review Jun 29, 2026
1 check passed
@MarsonShine MarsonShine deleted the marsonshine-optimize-test-coverage branch June 29, 2026 02:00

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

该 PR 以提升 CI 质量门禁的可信度为目标,集中补齐 AI Provider、领域事件溯源、EF Core 查询扩展与 Logging Provider 的关键分支与异常路径单元测试,并将代码覆盖率配置推广为解决方案级别生效。

Changes:

  • 新增/增强多处核心单测(AI:OpenAI Chat/Media、模型解析、生产选项校验;Domain:OrderAggregate 决策与折叠;EFCore:ApplySpecification;Logging:NLog/Serilog HostBuilder 重载)。
  • 覆盖率配置从 test/coverlet.runsettings 调整为解决方案根 coverlet.runsettings,并新增本地工具清单 dotnet-tools.json
  • 删除/精简部分低价值的 DTO/常量断言类测试。

Reviewed changes

Copilot reviewed 13 out of 13 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
test/MS.Microservice.Infrastructure.Tests/EventSourcing/OrderAggregateTests.cs 补齐确认/取消决策与重复加购、异常事件回放分支测试
test/MS.Microservice.Infrastructure.Tests/EventSourcing/OrderAggregateDecisionTests.cs 补齐重复创建、取消后修改、移除数量非法等冲突/校验分支测试
test/coverlet.runsettings 移除旧的测试目录 runsettings(不再作为统一入口)
coverlet.runsettings 新增根目录覆盖率 runsettings,期望对所有测试项目生效
dotnet-tools.json 增加 reportgenerator 本地工具清单,便于生成覆盖率报告
MS.Microservice.Persistence/MS.Microservice.Persistence.EFCore/test/MS.Microservice.Persistence.EFCore.Tests/MsPlatformDbContextSettingsTests.cs 删除仅验证 DTO 默认值/常量的低价值测试
MS.Microservice.Persistence/MS.Microservice.Persistence.EFCore/test/MS.Microservice.Persistence.EFCore.Tests/EfCoreQueryableExtensionsTests.cs 新增 ApplySpecification 排序/分页/投影/异常分支测试
MS.Microservice.Logging/test/MS.Microservice.Logging.Serilog.Tests/MsSerilogProviderTests.cs 增加 HostBuilder 重载配置后可写入 sink 的行为验证
MS.Microservice.Logging/test/MS.Microservice.Logging.NLog.Tests/MsNLogProviderTests.cs 将样例配置测试改为行为验证,并新增 HostBuilder 重载+请求上下文渲染测试
MS.Microservice.AI/test/MS.Microservice.AI.OpenAI.Tests/OpenAIMediaProviderTests.cs 增加 TTS/ASR 内容类型、内容安全、限流 retry-after、重试与超时分支测试
MS.Microservice.AI/test/MS.Microservice.AI.OpenAI.Tests/OpenAIChatProviderTests.cs 增加 OpenAI 配置校验(未引用/使用默认 base address/无效配置)测试
MS.Microservice.AI/test/MS.Microservice.AI.Core.Tests/DefaultAIModelResolverTests.cs 增加 provider/model 回退、场景大小写、缺省配置异常等模型解析分支测试
MS.Microservice.AI/test/MS.Microservice.AI.Core.Tests/AIProductionReadinessTests.cs 增加生产选项 validator 的失败/成功边界测试

Comment thread coverlet.runsettings
<RunSettings>
<DataCollectionRunSettings>
<DataCollectors>
<DataCollector friendlyName="XPlat code coverage">
Comment thread coverlet.runsettings
<Include>[MS.Microservice*]*</Include>
<Exclude>[*.Tests*]*</Exclude>
<ExcludeByAttribute>CompilerGeneratedAttribute,GeneratedCodeAttribute,DebuggerNonUserCodeAttribute,ExcludeFromCodeCoverageAttribute</ExcludeByAttribute>
<ExcludeByFile>**/bin/**/*.cs,**/obj/**/*.cs,**/Migrations/**/*.cs,**/Generated/**/*.cs,**/*.g.cs,**/*.g.i.cs,**/*.designer.cs,**/src/MS.Microservice.Core/Dto/**/*.cs,**/src/MS.Microservice.Web/Application/Models/**/*Request.cs,**/src/MS.Microservice.Web/Application/Models/**/*Response.cs,**/MS.Microservice.AI/src/MS.Microservice.AI.Abstractions/**/*Request.cs,**/MS.Microservice.AI/src/MS.Microservice.AI.Abstractions/**/*Response.cs,**/MS.Microservice.Swagger/SwaggerOptions.cs,**/MS.Microservice.Logging/src/MS.Microservice.Logging.Serilog/MsSerilogOptions.cs,**/MS.Microservice.Logging/src/MS.Microservice.Logging.NLog/MsNLogOptions.cs,**/MS.Microservice.Logging/src/MS.Microservice.Logging.AspNetCore/AspNetCoreRequestLoggingOptions.cs,**/MS.Microservice.AI/src/MS.Microservice.AI.Core/AIProductionOptions.cs,**/MS.Microservice.AI/src/MS.Microservice.AI.Core/AIOptions.cs,**/MS.Microservice.Persistence/MS.Microservice.Persistence.SqlSugar/src/MS.Microservice.Persistence.SqlSugar/SqlSugarOptions.cs,**/MS.Microservice.Persistence/MS.Microservice.Persistence.SqlSugar/src/MS.Microservice.Persistence.SqlSugar/SqlSugarClientBuilderOptions.cs,**/src/MS.Microservice.Web/Infrastructure/Cors/CorsOptions.cs,**/src/MS.Microservice.Domain/Identity/IdentityOptions.cs,**/src/MS.Microservice.Infrastructure/Caching/CacheOperationLogOptions.cs,**/src/MS.Microservice.Infrastructure/Caching/Buffer/BufferQueueOptions.cs,**/src/MS.Microservice.Infrastructure/Common/NAudio/AudioOptions.cs</ExcludeByFile>
[Fact]
public async Task SynthesizeAsync_WhenRateLimitedWithRetryAfterDate_ShouldExposeRetryAfter()
{
var retryAt = DateTimeOffset.UtcNow.AddSeconds(2);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants