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

发布于 2024-07-14 15:48:43 字数 130 浏览 9 评论 0原文

除了更好的可读性(也许?)以及能够使用 &| 链接约束之外,约束模型相对于经典模型还有哪些优势?

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

Besides better readability (maybe?) and being able to chain constraints using & and |, what other advantages does the Constraint Model have over the Classic Model?

I'm a happy user of the Classic Model, and I'm in the process of deciding whether it's worth the effort to refactor old tests.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

疧_╮線 2024-07-21 15:48:43

我不得不说我是“经典”模型的粉丝。 我发现在大多数情况下更容易表达我的主张,而且我发现它们也更容易阅读。 代码中没有任何东西是不必要的——没有“That”和“Is”,这听起来很流畅,但在我看来不利于被发现。

这很可能是由于熟悉以及其他原因,但我认为值得向您保证,您不是唯一一个认为经典模型完全合理的人:)话

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

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

I have to say I'm a fan of the "classic" model. I find it easier to formulate my assertions for the most part, and I find them easier to read too. There's nothing in the code which isn't necessary - no "That" and "Is" which sounds fluent but doesn't lend itself to discoverability IMO.

That may well be due to familiarity as much as anything else, but I thought it would just be worth reassuring you that you're not the only one who finds the classic model perfectly reasonable :)

Having said that, when there's something which is easier to express using constraints, it makes sense to use it. This is particularly true when there's some condition which can be explicitly tested with a constraint, but where the classic model would just use Assert.IsTrue(condition). The key point is that the constraint is likely to be able to give you more information than the classic one for such cases.

As such I think it's a good idea to learn the constraint-based model, but I wouldn't go as far as converting any tests, and I wouldn't use it where you find the classic model to be simpler or more readable.

智商已欠费 2024-07-21 15:48:43

我不知道除了可读性之外还有什么优点。 但这可能是一个很大的优势。 我发现,简单地使用 Assert.That( ... ) 开始每个测试,而不是使用一些 Assert 函数,可以使可视化扫描断言变得容易一百万倍,因为您不再需要费心有了函数名,就看参数了。

在 NUnit 2.4 中,两种语法(类和约束)在底层使用完全相同的代码。 不管怎样,幕后并没有什么优势。 除非你真的没有更好的时间利用,否则我不会费心重写测试。

I don't know that there are any other advantages besides readability. But that can be a big advantage. I find that simply starting every test with Assert.That( ... ) rather than having a handful of Assert functions makes it a million times easier to visually scan your asserts, since you no longer have to bother with the function name, just look at the arguments.

With NUnit 2.4, both syntaxes (class and constraint) use the exact same code underneath. There's no advantage behind the scenes one way or another. Unless you really have no better use for the time, I wouldn't bother rewriting tests.

风铃鹿 2024-07-21 15:48:43

NUnit 3 文档介绍了断言并将较新的约束模型与经典模型进行了比较,包括下面的例子:

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

 int[] 数组 = new int[] { 1, 2, 3 }; 
    Assert.That(数组, Has.Exactly(1).EqualTo(3)); 
    Assert.That(数组, Has.Exactly(2).GreaterThan(1)); 
    Assert.That(数组, 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());

有些可能得出这样的结论:约束我从文档中提取的模型测试比这些经典模型等效项更具可读性。 但这可以说是主观的。


然而,这并不是故事的全部。 更重要的是改进了失败的约束模型测试在测试失败时发出的错误消息 support>† 例如,考虑这个将失败的经典模型测试:

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帮助我理解错误消息中引入的这一重要改进约束模型。

The NUnit 3 documentation that introduces assertions and that compares the newer Constraint Model to the Classic Model includes the following example:

For example, the following code must use the constraint model. There
is no real classic equivalent.

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

While the document states that there is no "real classic equivalent," one could use Classic Syntax with LINQ to write what I would consider equivalent tests:

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

Some might conclude that the Constraint Model tests that I lifted from the documentation are more readable than these Classic Model equivalents. But that is arguably subjective.


However, that is not the whole story. More important is the improvement in the error message that a failed Constraint Model test emits when a test fails. For instance, consider this Classic Model test that will fail:

int[] array = new int[] { 1, 2, 3 };
Assert.AreEqual(1, array.Where(x => x == 4).Count());

The AssertionException that is thrown by NUnit contains the following "terse" Message:

    Expected: 1
    But was:  0

In contrast, when expressing this test in the newer Constraint Model syntax:

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

...NUnit returns the Message:

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

I think that most would agree that this exception message is much more helpful than the one produced using NUnit's older Classic Model syntax.


Much thanks to @nashwan for helping me understand this important improvement in the error messaging introduced in the Constraint Model.

睫毛上残留的泪 2024-07-21 15:48:43

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

举个例子,在不检查;-)的情况下,哪一个是正确的?

Assert.AreEqual(actual, expected);
Assert.AreEqual(expected, actual);

I personally prefer the Constraint Model Assert.That style and only use it now. I find this newer style more readable, and have determined that it is much less likely to get the "actual" and "expected" arguments mixed up. (Like you certainly can using the Classic Model Assert.AreEqual, etc., which I have seen many people do.) This obviously leads to broken tests that report incorrect results.

As an example, without checking ;-), which of these is correct?

Assert.AreEqual(actual, expected);
Assert.AreEqual(expected, actual);
深海夜未眠 2024-07-21 15:48:43

与经典模型相比,约束模型的一个主要优点是,某些断言可以写在一行中,而其中没有真正的经典模型等效项。

例如,这些约束模型没有真正的经典模型等效项:

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

可以找到源 这里

One main benefit of the constraint model over a classic model is that there are certain assertions that may be written in one line in which there are no real classic model equivalents.

For instance, these constraint model have no real classic model equivalents:

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

Source may be found here.

缱倦旧时光 2024-07-21 15:48:43

对其他答案中的观点进行了一点补充。 约束模型具有代码分析器,可以执行类型检查等操作。 例如,我对一个小函数进行了测试,将单个项目转换为 IEnumerable:

[Test]
public void Test_AsSingleton()
{
    var result = "A".AsSingleton();

    Assert.AreEqual(
        new[] { "A" },
        result);

    Assert.AreNotEqual(
        "A",
        result);
}

当将其转换为约束模型时,它正确地识别出第二个测试是多余的,因为类型不兼容。

A minor addition to the points made in other answers. The constraint model has code analyzers that will do things like type checking. For example, I had a test of a small function to convert a single item into an IEnumerable:

[Test]
public void Test_AsSingleton()
{
    var result = "A".AsSingleton();

    Assert.AreEqual(
        new[] { "A" },
        result);

    Assert.AreNotEqual(
        "A",
        result);
}

When this was converted to the constraint model, it correctly identified that the second test is redundant because the types are incompatible.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文