捕获 NUnit AssertionException 而不会在 C# 中测试失败
Catch NUnit AssertionException without failing test in C#
所以这是一个有点奇怪的设置。我正在将我们的测试从 MSTest(Visual Studio 单元测试)转移到 NUnit 3+。
在我原来的测试框架中,我添加了一个名为Verify的测试实用程序,其中进行了断言,但是异常suppressed/ignored,我们只是等到测试结束时断言是否发生任何失败.
public class Verify {
public static int NumExceptions = 0;
public static void AreEqual(int expected, int actual) {
try {
Assert.AreEqual(expected, actual);
} catch (AssertFailedException) {
NumExceptions++;
}
}
public static void AssertNoFailures() {
Assert.AreEqual(0, _numExceptions);
}
}
所以测试代码可能是:
[TestMethod]
public void VerifyPassesCorrectly() {
int x = 2;
int y = 3;
Verify.AreEqual(3, y);
Verify.AreEqual(2, x);
Verify.AreEqual(5, x + y);
Verify.AssertNoFailures();
}
[TestMethod]
[ExpectedException(typeof(AssertFailedException))]
public void VerifyCountsFailuresCorrectly() {
Verify.AreEqual(3, 2);
Assert.AreEqual(1, Verify.NumExceptions);
}
这两个测试都通过了,即使抛出 AssertFailedException
当我转向 NUnit 时,似乎有更好的方法来解决这个问题(警告、MultipleAssert)。最终,我们将构建新测试以利用这些改进。但是,与此同时,我需要为现有测试提供一些向后兼容性。
我最初的计划是简单地换出库并更改异常类型:
public static void AreEqual(int expected, int actual) {
try {
Assert.AreEqual(expected, actual);
} catch (AssertionException) {
NumExceptions++;
}
}
这不需要对现有测试代码进行实质性更改,也不需要真正对 Verify class 的结构进行更改。但是,当我使用 NUnit 适配器从 Visual Studio 中执行这样的测试时,第二个测试按预期运行(没有异常),但仍然未能通过测试,列出了在验证步骤中发现的异常。
更广泛的解决方案是简单地删除验证 class,因为有了 NUnit,它不再需要了。但在那之前,有没有办法在 Verify 中使用 NUnit API,以便 NUnit class 中的断言不会被 NUnit "stored" 用来使测试失败?
您将无法告诉 NUnit 断言不应以某种方式使测试失败。因此,您 可以 做的是更改 AreEqual 方法以仅自己进行相等性测试。
if (expected != actual) {
NumExceptions++;
}
这似乎是最简单的解决方案。
第二种选择是完全按照 NUnit 在其 Assert 语句中所做的操作。如果你想做 that(但当然不会导致测试失败)。代码如下所示:
public static void AreEqual(int expected, int actual) {
var equalToConstraint = Is.EqualTo(expected);
var result = equalToConstraint.ApplyTo(actual);
if (!result.IsSuccess) {
NumExceptions++;
}
}
Is
class 是 NUnit 的一部分,但它是 public,如果需要,您可以像这样使用它。
所以这是一个有点奇怪的设置。我正在将我们的测试从 MSTest(Visual Studio 单元测试)转移到 NUnit 3+。
在我原来的测试框架中,我添加了一个名为Verify的测试实用程序,其中进行了断言,但是异常suppressed/ignored,我们只是等到测试结束时断言是否发生任何失败.
public class Verify {
public static int NumExceptions = 0;
public static void AreEqual(int expected, int actual) {
try {
Assert.AreEqual(expected, actual);
} catch (AssertFailedException) {
NumExceptions++;
}
}
public static void AssertNoFailures() {
Assert.AreEqual(0, _numExceptions);
}
}
所以测试代码可能是:
[TestMethod]
public void VerifyPassesCorrectly() {
int x = 2;
int y = 3;
Verify.AreEqual(3, y);
Verify.AreEqual(2, x);
Verify.AreEqual(5, x + y);
Verify.AssertNoFailures();
}
[TestMethod]
[ExpectedException(typeof(AssertFailedException))]
public void VerifyCountsFailuresCorrectly() {
Verify.AreEqual(3, 2);
Assert.AreEqual(1, Verify.NumExceptions);
}
这两个测试都通过了,即使抛出 AssertFailedException
当我转向 NUnit 时,似乎有更好的方法来解决这个问题(警告、MultipleAssert)。最终,我们将构建新测试以利用这些改进。但是,与此同时,我需要为现有测试提供一些向后兼容性。
我最初的计划是简单地换出库并更改异常类型:
public static void AreEqual(int expected, int actual) {
try {
Assert.AreEqual(expected, actual);
} catch (AssertionException) {
NumExceptions++;
}
}
这不需要对现有测试代码进行实质性更改,也不需要真正对 Verify class 的结构进行更改。但是,当我使用 NUnit 适配器从 Visual Studio 中执行这样的测试时,第二个测试按预期运行(没有异常),但仍然未能通过测试,列出了在验证步骤中发现的异常。
更广泛的解决方案是简单地删除验证 class,因为有了 NUnit,它不再需要了。但在那之前,有没有办法在 Verify 中使用 NUnit API,以便 NUnit class 中的断言不会被 NUnit "stored" 用来使测试失败?
您将无法告诉 NUnit 断言不应以某种方式使测试失败。因此,您 可以 做的是更改 AreEqual 方法以仅自己进行相等性测试。
if (expected != actual) {
NumExceptions++;
}
这似乎是最简单的解决方案。
第二种选择是完全按照 NUnit 在其 Assert 语句中所做的操作。如果你想做 that(但当然不会导致测试失败)。代码如下所示:
public static void AreEqual(int expected, int actual) {
var equalToConstraint = Is.EqualTo(expected);
var result = equalToConstraint.ApplyTo(actual);
if (!result.IsSuccess) {
NumExceptions++;
}
}
Is
class 是 NUnit 的一部分,但它是 public,如果需要,您可以像这样使用它。