在 JUnit 中将单元测试标记为预期故障

2022-08-31 20:59:15

如何在 JUnit 4 中将测试标记为预期失败?

在这种情况下,我想继续运行此测试,直到上游修补了某些内容。忽略测试有点过分了,因为那样我可能会忘记它。我也许可以添加一个注释并捕获 由 引发的异常,但这似乎也谎报了预期的行为。@expectedassertThat

以下是我当前的测试:

@Test
public void unmarshalledDocumentHasExpectedValue() 
{
    doc = unmarshaller.unmarshal(getResourceAsStream("mydoc.xml"));
    final ST title = doc.getTitle();
    assertThat(doc.getTitle().toStringContent(), equalTo("Expected"));
}

该断言应该会成功,但由于上游错误,它没有成功。然而,这一检验是正确的。它应该成功。我发现的几乎所有替代方案都具有误导性。现在我认为是我最好的选择,但我仍然必须记得回到它。我更喜欢测试运行。@Ignore("This test should pass once fixed upstream")

在Python中,我可以使用预期的Failure装饰器:

class ExpectedFailureTestCase(unittest.TestCase):
    @unittest.expectedFailure
    def test_fail(self):
        self.assertEqual(1, 0, "broken")

使用Qt的QTestLib C++,您可以使用QEXPECT_FAIL

QEXPECT_FAIL("", "Will be fixed next version", Continue);
QCOMPARE(i, 42);

在上面的两种情况下,单元测试运行,这是我希望发生的事情。我在 JUnit 中遗漏了什么吗?


答案 1

我不太了解你的方案的细节,但以下是我通常测试预期故障的方法:

巧妙的新方式:

@Test(expected=NullPointerException.class)
public void expectedFailure() {
    Object o = null;
    o.toString();
}

对于较旧版本的 JUnit:

public void testExpectedFailure() {
    try {
        Object o = null;
        o.toString();
        fail("shouldn't get here");
    }
    catch (NullPointerException e) {
        // expected
    }
}

如果要确保抛出异常的一堆内容,则可能还希望在循环中使用第二种技术,而不是为每个情况创建单独的测试方法。如果您只是在单个方法中循环遍历一堆案例,则第一个引发异常的方法将结束测试,并且不会检查后续案例。expected


答案 2

明确期望断言错误怎么样?

@Test(expected = AssertionError.class)
public void unmarshalledDocumentHasExpectedValue() {
    // ...
}

如果你有理由相信只有测试中的JUnit机制会引发AsseritionError,那么这似乎和任何东西一样自我记录。

你仍然冒着忘记这种测试的风险。我不会让这样的测试长时间进入版本控制,如果有的话。


推荐