SuperAPI AI 工具集

fsharp-testing

测试与质量

查看项目

更新于 10-15 10:37

技能介绍

用途

本技能提供 F# 应用的全面测试模式,基于 xUnit、FsUnit、Unquote、FsCheck 以及现代 .NET 测试实践。适用于以下场景:为 F# 代码编写新测试;审查测试质量与覆盖率;为 F# 项目搭建测试基础设施;调试不稳定或缓慢的测试。

测试框架栈

  • xUnit:测试框架(.NET 生态标准选择)
  • FsUnit.xUnit:面向 xUnit 的 F# 友好断言语法
  • Unquote:使用 F# 引用的断言库,提供清晰的失败信息
  • FsCheck.xUnit:与 xUnit 集成的属性测试
  • NSubstitute:模拟 .NET 依赖
  • Testcontainers:集成测试中的真实基础设施
  • WebApplicationFactory:ASP.NET Core 集成测试

主要能力

使用 xUnit + FsUnit 的单元测试

基本测试结构使用 [<Fact>] 特性,配合 FsUnit 的 should equal、should be (ofCase ...) 等断言。

使用 Unquote 的断言

Unquote 使用 F# 引用,失败信息会展示完整失败表达式,而不仅是“期望 X 得到 Y”。使用 test <@ ... @> 进行断言。

异步测试

使用 task { ... } 计算表达式编写异步测试,配合 let! 等待异步操作。

参数化测试

使用 [<Theory>] 与 [<InlineData(...)>] 提供多组输入数据。

使用 FsCheck 的属性测试

通过 [<Property>] 特性定义属性,可使用 NonEmptyList、PositiveInt 等生成器,并支持自定义生成器(通过 Arb.fromGen 与 Arbitrary 参数)。

模拟依赖

推荐使用函数桩(function stubs)方式,通过记录类型组合可替换函数;对于 .NET 接口可使用 NSubstitute。

ASP.NET Core 集成测试

使用 WebApplicationFactory<Program> 与 IClassFixture,可替换数据库为内存数据库进行测试。

使用方式

测试组织建议目录结构:

tests/
  MyApp.Tests/
    Unit/
      OrderServiceTests.fs
      PaymentServiceTests.fs
    Integration/
      OrderApiTests.fs
      OrderRepositoryTests.fs
    Properties/
      OrderPropertyTests.fs
    Helpers/
      TestData.fs
      TestDeps.fs

运行测试命令:

# 运行所有测试
dotnet test

# 带覆盖率运行
dotnet test --collect:"XPlat Code Coverage"

# 运行特定项目
dotnet test tests/MyApp.Tests/

# 按测试名过滤
dotnet test --filter "FullyQualifiedName~OrderService"

# 开发期间监视模式
dotnet watch test --project tests/MyApp.Tests/

适用场景

  • F# 项目的单元测试、属性测试与集成测试编写
  • 测试基础设施搭建与测试组织
  • 测试质量与覆盖率审查
  • 不稳定或缓慢测试的调试

限制与注意事项

资料中列出了常见反模式及修复建议:测试实现细节应改为测试行为与结果;可变共享测试状态应改为每个测试使用全新状态;异步测试中避免 Thread.Sleep,应使用带超时的 Task.Delay 或轮询辅助;避免对 sprintf 输出断言,应断言类型化值与模式匹配;不要忽略 CancellationToken,应始终传递并验证取消;不要跳过属性测试,对任何具有明确不变量的函数使用 FsCheck。

相关技能包括 dotnet-patterns(惯用 .NET 模式、依赖注入与架构)和 csharp-testing(C# 测试模式,其中 WebApplicationFactory 与 Testcontainers 等共享基础设施同样适用于 F#)。