NUnit中约束模型优于经典模型的优势?

问题描述 投票:23回答:4

除了更好的可读性(可能?)并且能够使用&|链接约束之外,Constraint模型还有哪些优于经典模型的优势?

我是经典模型的快乐用户,我正在决定是否值得重构旧测试。

unit-testing nunit
4个回答
18
投票

我不得不说我是“经典”模特的粉丝。我发现在大多数情况下更容易制定我的断言,我发现它们也更容易阅读。代码中没有任何内容是没有必要的 - 没有“那个”和“是”这听起来流畅但不适合发现IMO。

这很可能是由于熟悉和其他任何东西一样,但我认为你不是唯一一个发现经典模型完全合理的人,这是值得的。

话虽如此,当使用约束更容易表达的东西时,使用它是有意义的。当某些条件可以使用约束进行显式测试时,尤其如此,但经典模型只使用Assert.IsTrue(condition)。关键点在于约束可能能够为这种情况提供比经典约束更多的信息。

因此我认为学习基于约束的模型是一个好主意,但我不会转换任何测试,我不会在你发现经典模型更简单或更易读的地方使用它。


14
投票

我不知道除了可读性之外还有其他任何优点。但这可能是一个很大的优势。我发现简单地使用Assert.That( ... )开始每个测试而不是使用少量的Assert函数使得在视觉上扫描断言容易一百万次,因为您不再需要打扰函数名称,只需查看参数即可。

使用NUnit 2.4,两种语法(类和约束)都使用完全相同的代码。这种或那种方式背后没有任何优势。除非你真的没有更好的时间使用,否则我不打算重写测试。


3
投票

引入断言并将较新的约束模型与经典模型进行比较的NUnit 3 documentation包括以下示例:

例如,以下代码必须使用约束模型。没有真正的经典等价物。

  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));

虽然文档声明没有“真正的经典等价物”,但可以使用经典语法和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

相反,在较新的Constraint Model语法中表达此测试时:

Assert.That(array, Has.Exactly(1).EqualTo(4));

... NUnit返回Message

    Expected: exactly one item equal to 4
    But was:  < 1, 2, 3 >

我认为大多数人会同意这个异常消息比使用NUnit的旧经典模型语法生成的消息更有帮助。


†非常感谢@nashwan帮助我理解Constraint模型中引入的错误消息的这一重要改进。


2
投票

我个人更喜欢Constraint Model Assert.That风格,现在只使用它。我发现这种新风格更具可读性,并且已经确定将“实际”和“预期”参数混淆的可能性要小得多。 (就像你当然可以使用经典模型Assert.AreEqual等,我见过许多人这样做。)这显然会导致破坏的测试报告错误的结果。

举个例子,没有检查;-),哪些是正确的?

Assert.AreEqual(actual, expected);
Assert.AreEqual(expected, actual);
© www.soinside.com 2019 - 2024. All rights reserved.