csharp-nunit

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

NUnit Best Practices

NUnit单元测试最佳实践

Your goal is to help me write effective unit tests with NUnit, covering both standard and data-driven testing approaches.
你的目标是帮助我编写高效的NUnit单元测试,涵盖标准测试和数据驱动测试两种方法。

Project Setup

项目设置

  • Use a separate test project with naming convention
    [ProjectName].Tests
  • Reference Microsoft.NET.Test.Sdk, NUnit, and NUnit3TestAdapter packages
  • Create test classes that match the classes being tested (e.g.,
    CalculatorTests
    for
    Calculator
    )
  • Use .NET SDK test commands:
    dotnet test
    for running tests
  • 使用单独的测试项目,命名规范为
    [项目名称].Tests
  • 引用Microsoft.NET.Test.Sdk、NUnit和NUnit3TestAdapter包
  • 创建与被测类对应的测试类(例如,为
    Calculator
    创建
    CalculatorTests
  • 使用.NET SDK测试命令:
    dotnet test
    来运行测试

Test Structure

测试结构

  • Apply
    [TestFixture]
    attribute to test classes
  • Use
    [Test]
    attribute for test methods
  • Follow the Arrange-Act-Assert (AAA) pattern
  • Name tests using the pattern
    MethodName_Scenario_ExpectedBehavior
  • Use
    [SetUp]
    and
    [TearDown]
    for per-test setup and teardown
  • Use
    [OneTimeSetUp]
    and
    [OneTimeTearDown]
    for per-class setup and teardown
  • Use
    [SetUpFixture]
    for assembly-level setup and teardown
  • 为测试类应用
    [TestFixture]
    特性
  • 为测试方法使用
    [Test]
    特性
  • 遵循Arrange-Act-Assert(AAA)模式
  • 使用
    方法名_场景_预期行为
    的模式命名测试
  • 使用
    [SetUp]
    [TearDown]
    进行每个测试的初始化和清理
  • 使用
    [OneTimeSetUp]
    [OneTimeTearDown]
    进行每个测试类的初始化和清理
  • 使用
    [SetUpFixture]
    进行程序集级别的初始化和清理

Standard Tests

标准测试

  • Keep tests focused on a single behavior
  • Avoid testing multiple behaviors in one test method
  • Use clear assertions that express intent
  • Include only the assertions needed to verify the test case
  • Make tests independent and idempotent (can run in any order)
  • Avoid test interdependencies
  • 保持测试专注于单一行为
  • 避免在一个测试方法中测试多个行为
  • 使用清晰的断言来表达意图
  • 只包含验证测试用例所需的断言
  • 确保测试独立且幂等(可以按任意顺序运行)
  • 避免测试之间的依赖

Data-Driven Tests

数据驱动测试

  • Use
    [TestCase]
    for inline test data
  • Use
    [TestCaseSource]
    for programmatically generated test data
  • Use
    [Values]
    for simple parameter combinations
  • Use
    [ValueSource]
    for property or method-based data sources
  • Use
    [Random]
    for random numeric test values
  • Use
    [Range]
    for sequential numeric test values
  • Use
    [Combinatorial]
    or
    [Pairwise]
    for combining multiple parameters
  • 使用
    [TestCase]
    进行内联测试数据
  • 使用
    [TestCaseSource]
    进行程序化生成的测试数据
  • 使用
    [Values]
    进行简单的参数组合
  • 使用
    [ValueSource]
    进行基于属性或方法的数据源
  • 使用
    [Random]
    生成随机数值测试数据
  • 使用
    [Range]
    生成连续数值测试数据
  • 使用
    [Combinatorial]
    [Pairwise]
    来组合多个参数

Assertions

断言

  • Use
    Assert.That
    with constraint model (preferred NUnit style)
  • Use constraints like
    Is.EqualTo
    ,
    Is.SameAs
    ,
    Contains.Item
  • Use
    Assert.AreEqual
    for simple value equality (classic style)
  • Use
    CollectionAssert
    for collection comparisons
  • Use
    StringAssert
    for string-specific assertions
  • Use
    Assert.Throws<T>
    or
    Assert.ThrowsAsync<T>
    to test exceptions
  • Use descriptive messages in assertions for clarity on failure
  • 使用
    Assert.That
    搭配约束模型(NUnit推荐风格)
  • 使用诸如
    Is.EqualTo
    Is.SameAs
    Contains.Item
    等约束
  • 使用
    Assert.AreEqual
    进行简单值相等性判断(经典风格)
  • 使用
    CollectionAssert
    进行集合比较
  • 使用
    StringAssert
    进行字符串特定断言
  • 使用
    Assert.Throws<T>
    Assert.ThrowsAsync<T>
    测试异常
  • 在断言中使用描述性消息,以便在失败时清晰说明问题

Mocking and Isolation

模拟与隔离

  • Consider using Moq or NSubstitute alongside NUnit
  • Mock dependencies to isolate units under test
  • Use interfaces to facilitate mocking
  • Consider using a DI container for complex test setups
  • 考虑搭配使用Moq或NSubstitute与NUnit
  • 模拟依赖项以隔离被测单元
  • 使用接口来简化模拟
  • 复杂测试设置时考虑使用DI容器

Test Organization

测试组织

  • Group tests by feature or component
  • Use categories with
    [Category("CategoryName")]
  • Use
    [Order]
    to control test execution order when necessary
  • Use
    [Author("DeveloperName")]
    to indicate ownership
  • Use
    [Description]
    to provide additional test information
  • Consider
    [Explicit]
    for tests that shouldn't run automatically
  • Use
    [Ignore("Reason")]
    to temporarily skip tests
  • 按功能或组件对测试进行分组
  • 使用
    [Category("分类名称")]
    添加分类
  • 必要时使用
    [Order]
    控制测试执行顺序
  • 使用
    [Author("开发者名称")]
    标注所有者
  • 使用
    [Description]
    提供额外的测试信息
  • 对于不应自动运行的测试,考虑使用
    [Explicit]
  • 使用
    [Ignore("原因")]
    临时跳过测试