C产品如何满足特定用户需求?
- 内容介绍
- 文章标签
- 相关推荐
本文共计882个文字,预计阅读时间需要4分钟。
NUnit 测试不会自动发现测试,必须手动满足以下条件:
-
[TestFixture]不是必需的——NUnit 3.x 起已废弃该属性,加了也不报错,但纯属冗余 - 类名或方法名含空格、中文、特殊符号(如
Add_2+3=5),可能导致测试显示为灰色或无法执行 - 若用 .NET SDK 风格项目(
<PackageReference>),确保NUnit和NUnit3TestAdapter版本匹配:NUnit 3.13+ 对应 NUnit3TestAdapter 4.x;混用 NUnit 4.x 和旧版 Adapter 会导致测试完全不出现
Assert.AreEqual 比较失败?先看类型和语义
Assert.AreEqual 看似简单,但对引用类型默认做引用比较,不是内容比较。比如两个新构造的 List<int>{1,2},AreEqual 会返回 false——这不是 bug,是设计行为。
- 值类型、字符串、实现
IEquatable<T>的类型可用AreEqual - 自定义类想用
AreEqual,必须重写Equals和GetHashCode,否则仍比引用 - 浮点数比较严禁直接用
AreEqual,改用Assert.That(actual, Is.EqualTo(expected).Within(delta))或Assert.AreApproximatelyEqual(expected, actual, delta) - 更推荐统一用
Assert.That链式语法:语义清晰(如Is.Null.Or.Empty)、支持约束组合、调试时错误信息更具体
怎么传参跑多组数据?用 TestCase 而不是手写循环
别在 [Test] 方法里写 foreach 跑多个输入——那样只算一个测试用例,失败时无法定位具体哪组数据出问题。
- 用
[TestCase(1, 2, 3)]、[TestCase(-5, 0, -5)]直接声明多组输入,每组生成独立测试项 - 参数顺序必须与方法签名严格一致,否则编译通过但运行时报
ArgumentException - 支持混合类型:
[TestCase("hello", 5, true)]对应public void Test(string s, int len, bool expected) - 若需大量或动态数据,改用
[TestCaseSource]指向静态方法或属性,返回object[]数组
测试前要初始化对象?SetUp 比构造函数更可靠
别在测试类构造函数里初始化被测实例——NUnit 不保证构造函数调用时机,且可能复用实例导致状态污染。
- 用
[SetUp]方法(返回void,无参数)做每次测试前的干净初始化 - 对应清理用
[TearDown],比如释放文件句柄、关闭 mock 数据库连接 - 全类共用一次的开销(如启动 mock server)放
[OneTimeSetUp],注意它不能访问实例字段,只能操作static成员 -
[SetUp]和[Test]方法都必须是public,否则静默失效
最容易被忽略的是版本兼容性和断言语义——NUnit 的 AreEqual 和 xUnit 的 Equal 表面相似,底层逻辑完全不同;Adapter 版本错配时测试“消失”没有提示,只会安静地不运行。动手前先确认包版本和方法修饰符,比写十个测试都重要。
本文共计882个文字,预计阅读时间需要4分钟。
NUnit 测试不会自动发现测试,必须手动满足以下条件:
-
[TestFixture]不是必需的——NUnit 3.x 起已废弃该属性,加了也不报错,但纯属冗余 - 类名或方法名含空格、中文、特殊符号(如
Add_2+3=5),可能导致测试显示为灰色或无法执行 - 若用 .NET SDK 风格项目(
<PackageReference>),确保NUnit和NUnit3TestAdapter版本匹配:NUnit 3.13+ 对应 NUnit3TestAdapter 4.x;混用 NUnit 4.x 和旧版 Adapter 会导致测试完全不出现
Assert.AreEqual 比较失败?先看类型和语义
Assert.AreEqual 看似简单,但对引用类型默认做引用比较,不是内容比较。比如两个新构造的 List<int>{1,2},AreEqual 会返回 false——这不是 bug,是设计行为。
- 值类型、字符串、实现
IEquatable<T>的类型可用AreEqual - 自定义类想用
AreEqual,必须重写Equals和GetHashCode,否则仍比引用 - 浮点数比较严禁直接用
AreEqual,改用Assert.That(actual, Is.EqualTo(expected).Within(delta))或Assert.AreApproximatelyEqual(expected, actual, delta) - 更推荐统一用
Assert.That链式语法:语义清晰(如Is.Null.Or.Empty)、支持约束组合、调试时错误信息更具体
怎么传参跑多组数据?用 TestCase 而不是手写循环
别在 [Test] 方法里写 foreach 跑多个输入——那样只算一个测试用例,失败时无法定位具体哪组数据出问题。
- 用
[TestCase(1, 2, 3)]、[TestCase(-5, 0, -5)]直接声明多组输入,每组生成独立测试项 - 参数顺序必须与方法签名严格一致,否则编译通过但运行时报
ArgumentException - 支持混合类型:
[TestCase("hello", 5, true)]对应public void Test(string s, int len, bool expected) - 若需大量或动态数据,改用
[TestCaseSource]指向静态方法或属性,返回object[]数组
测试前要初始化对象?SetUp 比构造函数更可靠
别在测试类构造函数里初始化被测实例——NUnit 不保证构造函数调用时机,且可能复用实例导致状态污染。
- 用
[SetUp]方法(返回void,无参数)做每次测试前的干净初始化 - 对应清理用
[TearDown],比如释放文件句柄、关闭 mock 数据库连接 - 全类共用一次的开销(如启动 mock server)放
[OneTimeSetUp],注意它不能访问实例字段,只能操作static成员 -
[SetUp]和[Test]方法都必须是public,否则静默失效
最容易被忽略的是版本兼容性和断言语义——NUnit 的 AreEqual 和 xUnit 的 Equal 表面相似,底层逻辑完全不同;Adapter 版本错配时测试“消失”没有提示,只会安静地不运行。动手前先确认包版本和方法修饰符,比写十个测试都重要。

