【发布时间】:2010-10-13 13:31:50
【问题描述】:
除了更好的可读性(也许?)和能够使用& 和| 链接约束之外,约束模型与经典模型相比还有哪些其他优势?
我是经典模型的快乐用户,我正在决定是否值得努力重构旧测试。
【问题讨论】:
标签: unit-testing nunit
除了更好的可读性(也许?)和能够使用& 和| 链接约束之外,约束模型与经典模型相比还有哪些其他优势?
我是经典模型的快乐用户,我正在决定是否值得努力重构旧测试。
【问题讨论】:
标签: unit-testing nunit
我不知道除了可读性之外还有什么其他优点。但这可能是一个很大的优势。我发现只需使用Assert.That( ... ) 开始每个测试,而不是使用少量的 Assert 函数,就可以轻松一百万倍地直观地扫描您的断言,因为您不再需要为函数名称而烦恼,只需查看参数即可。
在 NUnit 2.4 中,两种语法(类和约束)都使用完全相同的代码。无论哪种方式,幕后都没有优势。除非你真的没有更好的时间利用时间,否则我不会费心重写测试。
【讨论】:
我不得不说我是“经典”模型的粉丝。我发现在大多数情况下更容易制定我的断言,而且我发现它们也更容易阅读。代码中没有任何不必要的内容 - 没有“那个”和“是”,它们听起来很流畅,但不适合 IMO 的可发现性。
这很可能是由于熟悉程度不亚于其他原因,但我认为值得向您保证,您不是唯一一个认为经典模型完全合理的人 :)
话虽如此,当使用约束更容易表达某些东西时,使用它是有意义的。当某些条件可以显式通过约束进行测试时尤其如此,但经典模型只使用Assert.IsTrue(condition)。关键在于,对于此类情况,约束可能比经典约束提供更多信息。
因此,我认为学习基于约束的模型是个好主意,但我不会去转换任何测试,也不会在你找到经典模型更简单或更易读。
【讨论】:
Assert.That(foo, Is.Equal(...)) 的额外冗长并不吸引人。 (同样,虽然许多人讨厌在测试中使用多个断言的想法,但如果它正在测试一个逻辑流程,我可以接受。如果一个测试失败,那几乎总是等同于不止一个失败......)跨度>
我个人更喜欢约束模型Assert.That 风格,现在才使用。我发现这种较新的风格更具可读性,并且已经确定它不太可能混淆“实际”和“预期”的论点。 (就像你当然可以使用经典模型 Assert.AreEqual 等,我见过很多人这样做。)这显然会导致报告错误结果的测试失败。
举个例子,不检查 ;-),哪些是正确的?
Assert.AreEqual(actual, expected);
Assert.AreEqual(expected, actual);
【讨论】:
AreEqual,这些论点的顺序真的很重要吗?也许Assert.Greater(value1, value2) 是一个更好的例子来说明经典模型中这种潜在的歧义?
引入断言并将较新的约束模型与经典模型进行比较的NUnit 3 documentation 包括以下示例:
例如,以下代码必须使用约束模型。那里 不是真正的经典等价物。
整数 [] 数组 = 新整数 [] { 1, 2, 3 }; Assert.That(array, Has.Exactly(1).EqualTo(3)); Assert.That(array, Has.Exactly(2).GreaterThan(1)); Assert.That(array, Has.Exactly(3).LessThan(100));
虽然文档指出没有“真正的经典等效”,但可以将经典语法与 LINQ 结合使用来编写我认为等效的测试:
Assert.AreEqual(1, array.Where(x => x == 3).Count());
Assert.AreEqual(2, array.Where(x => x > 1).Count());
Assert.AreEqual(3, array.Where(x => x < 100).Count());
有些人可能得出结论,我从文档中提取的约束模型测试比这些经典模型等效项更具可读性。但这可以说是主观的。
然而,这还不是全部。更重要的是改进了错误消息,失败的约束模型测试在测试失败时发出。† 例如,考虑这个将失败的经典模型测试:
int[] array = new int[] { 1, 2, 3 };
Assert.AreEqual(1, array.Where(x => x == 4).Count());
NUnit 抛出的AssertionException 包含以下“简洁”Message:
Expected: 1
But was: 0
相比之下,当用新的约束模型语法表达这个测试时:
Assert.That(array, Has.Exactly(1).EqualTo(4));
...NUnit 返回Message:
Expected: exactly one item equal to 4
But was: < 1, 2, 3 >
我认为大多数人都会同意,此异常消息比使用 NUnit 的旧经典模型语法生成的异常消息更有帮助。
† 非常感谢 @nashwan 帮助我了解约束模型中引入的错误消息的这一重要改进。
【讨论】:
约束模型相对于经典模型的一个主要好处是,某些断言可以写在一行中,而其中没有真正的经典模型等价物。
例如,这些约束模型没有真正的经典模型等价物:
int[] array = new int[] { 1, 2, 3 };
Assert.That(array, Has.Exactly(1).EqualTo(3));
Assert.That(array, Has.Exactly(2).GreaterThan(1));
Assert.That(array, Has.Exactly(3).LessThan(100));
来源可以在here找到。
【讨论】: