csharp-xunit

csharp-xunit

热门

获取 XUnit 单元测试的最佳实践,包括数据驱动测试

3.6万Star
0Fork
更新于 2026/7/11
SKILL.md
readonly只读
name
csharp-xunit
description

获取 XUnit 单元测试的最佳实践,包括数据驱动测试

XUnit 最佳实践

您的目标是帮助我使用 XUnit 编写有效的单元测试,涵盖标准测试和数据驱动测试方法。

项目设置

  • 使用单独的测试项目,命名约定为 [ProjectName].Tests
  • 引用 Microsoft.NET.Test.Sdk、xunit 和 xunit.runner.visualstudio 包
  • 创建与被测试类匹配的测试类(例如,CalculatorTests 对应 Calculator
  • 使用 .NET SDK 测试命令:dotnet test 运行测试

测试结构

  • 不需要测试类属性(与 MSTest/NUnit 不同)
  • 对于简单测试,使用带有 [Fact] 属性的基于事实的测试
  • 遵循 Arrange-Act-Assert (AAA) 模式
  • 使用 MethodName_Scenario_ExpectedBehavior 模式命名测试
  • 使用构造函数进行设置,使用 IDisposable.Dispose() 进行清理
  • 使用 IClassFixture<T> 在类中的测试之间共享上下文
  • 使用 ICollectionFixture<T> 在多个测试类之间共享上下文

标准测试

  • 保持测试专注于单一行为
  • 避免在一个测试方法中测试多个行为
  • 使用清晰的断言来表达意图
  • 仅包含验证测试用例所需的断言
  • 使测试独立且幂等(可以按任意顺序运行)
  • 避免测试之间的相互依赖

数据驱动测试

  • 使用 [Theory] 结合数据源属性
  • 使用 [InlineData] 提供内联测试数据
  • 使用 [MemberData] 提供基于方法的测试数据
  • 使用 [ClassData] 提供基于类的测试数据
  • 通过实现 DataAttribute 创建自定义数据属性
  • 在数据驱动测试中使用有意义的参数名称

断言

  • 使用 Assert.Equal 进行值相等性比较
  • 使用 Assert.Same 进行引用相等性比较
  • 使用 Assert.True/Assert.False 进行布尔条件判断
  • 使用 Assert.Contains/Assert.DoesNotContain 进行集合检查
  • 使用 Assert.Matches/Assert.DoesNotMatch 进行正则表达式模式匹配
  • 使用 Assert.Throws<T>await Assert.ThrowsAsync<T> 测试异常
  • 使用流畅断言库以获得更可读的断言

模拟和隔离

  • 考虑将 Moq 或 NSubstitute 与 XUnit 一起使用
  • 模拟依赖项以隔离被测单元
  • 使用接口以方便模拟
  • 对于复杂的测试设置,考虑使用 DI 容器

测试组织

  • 按功能或组件对测试进行分组
  • 使用 [Trait("Category", "CategoryName")] 进行分类
  • 使用集合夹具对具有共享依赖项的测试进行分组
  • 考虑使用输出助手(ITestOutputHelper)进行测试诊断
  • 使用事实/理论属性中的 Skip = "reason" 有条件地跳过测试