如何指定 NUnit 测试应该失败?

发布于 2024-10-08 20:01:23 字数 412 浏览 2 评论 0原文

有没有办法指定您希望 NUnit 测试失败,这意味着失败应报告为通过,而通过应报告为失败?这在测试您自己的 NUnit 扩展时非常有用。这是我希望能够执行的操作的示例:

[Test]
[ExpectFail]
public void TypeOf_fail() {
    string str = "abc";
    str.Should().Be.TypeOf<int>();
}

这不会编译,因为 [ExpectFail] 是一个虚构的属性,用于说明我想要执行的操作,但方法内的代码工作正常。此问题特定于测试 NUnit 扩展,因为您通常可以轻松编写测试以通过,而不是失败。在这种情况下,您需要证明可以使用您正在测试的 NUnit 扩展编写失败的测试。

Is there a way to specify that you want an NUnit test to fail, meaning that a fail should be reported as a pass and a pass should be reported as a fail? This would be useful when testing your own NUnit extensions. Here is an example of something I would like to be able to do:

[Test]
[ExpectFail]
public void TypeOf_fail() {
    string str = "abc";
    str.Should().Be.TypeOf<int>();
}

This does not compile because [ExpectFail] is an imaginary attribute to illustrate what I want to do, but the code inside the method works fine. This problem is specific to testing an NUnit extension in that you can normally just easily write your tests to pass, not fail. In this case you need prove that it is possible to write a failing test using the NUnit extension that you are testing.

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

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

发布评论

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

评论(4

So要识趣 2024-10-15 20:01:23

我知道这是一篇旧帖子,但以下是使用 NUnit 对我有帮助的内容:

[TestCase("SomeValidValue")]
[TestCase("{3X5XFX9X-7XCX-4XCX-8X3X-3XAXEX9X0XBX}", ExpectedException = typeof(AssertionException))]
public void GetSpecificConfiguration(string key)
{
    Assert.IsNotNull(Config.Instance.GetRecord(key));
}

这种方法允许我进行相同的测试,有两种期望,一种成功,一种失败。

I know this is an old post, but here is what has helped me, using NUnit:

[TestCase("SomeValidValue")]
[TestCase("{3X5XFX9X-7XCX-4XCX-8X3X-3XAXEX9X0XBX}", ExpectedException = typeof(AssertionException))]
public void GetSpecificConfiguration(string key)
{
    Assert.IsNotNull(Config.Instance.GetRecord(key));
}

This approach allows me to have the same test, with two expectations, one succeeding, and one failing.

心病无药医 2024-10-15 20:01:23

单元测试的设计应使得:
他们建立了一些状态
他们运行测试下的方法
他们断言,在被测试的方法完成后,有一件事是正确的

(参考:Roy Osherove 的《单元测试的艺术》)

为什么设计为失败的测试是一件坏事?他们可能会以意想不到的方式失败,但仍然会因为失败而被标记为通过。在您的示例中,假设 Should() 是被测试的方法(尽管即使不是,这一点仍然存在),您编写上面的测试并将其标记为“预期失败”。它失败了。一切都很好。几个月后,您回到 Should() 并意识到它需要一些重构,因此您更改了它的实现。

现在,在您的示例中,Should() 抛出异常,因为您不小心引入了错误。但是您的测试(由于现在的异常而不是逻辑而失败)被标记为应该失败,而且它确实失败了,因此尽管发生了重大更改,它仍然被标记为通过。

测试应该设计为通过,而不是失败,这样,如果它以另一种意外的方式失败,您将会收到通知。因此,在您的示例中,您应该使用相反的逻辑编写测试:

[Test]
public void TypeOf_ShouldBeString() {
    string str = "abc";
    str.Should().Be.TypeOf<string>();
}

或:(

[Test]
public void TypeOf_ShouldNotBeInt() {
    string str = "abc";
    str.Should().Not.Be.TypeOf<int>();
}

不确定您正在使用的语法,因此 .Not 可能需要用正确的语法替换,但情感仍然成立)。

Edit2:如果您想要做的是确保您的 Should() 方法失败(通过 Assert. 方法失败),那么您要做的就是捕获 Assert. 方法中的 NUnit AssertionException 。静态方法抛出。试试这个:

[Test]
[ExpectedException(typeof(AssertionException))]
public void ShouldBeTypeOf_WithInt_Fails() {
    string str = "abc";
    str.Should().Be.TypeOf<int>();
}    

Unit tests should be designed so that:
They set up some state
They run the method under test
They assert that one thing is correct after the method under test has completed

(reference: The Art of Unit Testing by Roy Osherove)

Why are tests that are designed to fail a bad thing? They could fail in unexpected ways, and still be marked as a pass because they failed. In your example, assuming that Should() is the method under test (though this point remains even if it isn't), you write the test above and mark it as 'expected to fail'. It fails. Everything is fine. In a couple of months you come back to Should() and realise it needs some refactoring, so you change its implementation.

Now, in your example, Should() throws an exception, because you've accidentally introduced a bug. But your test (which fails because of the exception now, not the logic) is marked as should fail, and it does, so it's still marked as a pass, despite the breaking change.

The test should be designed to pass, not to fail, that way if it fails in another, unexpected, way you'll be notified. So in your example you should write tests with opposite logic:

[Test]
public void TypeOf_ShouldBeString() {
    string str = "abc";
    str.Should().Be.TypeOf<string>();
}

or:

[Test]
public void TypeOf_ShouldNotBeInt() {
    string str = "abc";
    str.Should().Not.Be.TypeOf<int>();
}

(Not sure of the syntax you're using, so .Not probably will need replacing with the correct syntax, but the sentiment holds).

Edit2: If what you're trying to do is ensure that your Should() method fails (by failing an Assert. method) then what you want to do is catch the NUnit AssertionException which the Assert. static methods throw. Try this:

[Test]
[ExpectedException(typeof(AssertionException))]
public void ShouldBeTypeOf_WithInt_Fails() {
    string str = "abc";
    str.Should().Be.TypeOf<int>();
}    
時窥 2024-10-15 20:01:23

怎么样 Assert.Throws(x.DoSomething());

这里的好处是,如果测试通过(即抛出异常),则返回值是实际的异常本身,然后您可以询问它并在此基础上进一步断言。

鉴于在这种情况下您想要测试 NUnit 扩展,我假设它通过进行 Assert 调用来起作用,您可以 Assert.ThrowsAssert.Throws< AssertionException>(...),,然后执行上述操作。

我正在考虑编写一些类似的测试管道代码,我可能需要对其进行测试,所以如果我在该领域发现任何其他内容,我会让您知道。

What about Assert.Throws<XXXException>(x.DoSomething());

The nice thing here is that if the test passes (i.e. the exception was thrown), the return value is the actual exception itself, and you can then interrogate it and Assert further based on that..

Given that in this case you're wanting to test NUnit extensions, which, I'm assuming, function by making Assert calls, you could Assert.Throws<AssertionException>(...), and then do the above.

I'm thinking of writing some similar test plumbing code which I might in turn need tests for, so I'll let you know if I discover anything else in this area.

雪花飘飘的天空 2024-10-15 20:01:23

如果您的意思是代码块预计会抛出异常以使测试通过,则代码如下:

[Test]
[ExpectedException(typeof(Exception))]
public void TypeOf_fail() {
    string str = "abc";
    str.Should().Be.TypeOf<int>();
}

当然,请将 Exception 替换为可能的最具体的异常。

If you mean that the block of code is expected to throw an exception for test to pass, here's the code:

[Test]
[ExpectedException(typeof(Exception))]
public void TypeOf_fail() {
    string str = "abc";
    str.Should().Be.TypeOf<int>();
}

Of course, replace Exception with the most specific exception possible.

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