当前位置: 首页 > 面试题库 >

在JUnit中将单元测试标记为预期的失败

汲雅珺
2023-03-14
问题内容

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

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

这是我当前的测试结果:

@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我可以使用expectedFailure装饰:

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

借助Ct中的Qt的QTestLib,您可以使用QEXPECT_FAIL:

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

在以上两种情况下,我都希望进行单元测试。我在JUnit中缺少什么吗?


问题答案:

我在这里假设,如果断言失败,您希望测试通过,但是如果断言成功,那么测试也应该通过。

最简单的方法是使用TestRule。TestRule提供了在运行测试方法之前和之后执行代码的机会。这是一个例子:

public class ExpectedFailureTest {
    public class ExpectedFailure implements TestRule {
        public Statement apply(Statement base, Description description) {
            return statement(base, description);
        }

        private Statement statement(final Statement base, final Description description) {
            return new Statement() {
                @Override
                public void evaluate() throws Throwable {
                    try {
                        base.evaluate();
                    } catch (Throwable e) {
                        if (description.getAnnotation(Deprecated.class) != null) {
                            // you can do whatever you like here.
                            System.err.println("test failed, but that's ok:");
                        } else {
                            throw e;
                        }
                    }
                }
            };
        }
    }

    @Rule public ExpectedFailure expectedFailure = new ExpectedFailure();

    // actually fails, but we catch the exception and make the test pass.
    @Deprecated
    @Test public void testExpectedFailure() {
        Object o = null;
        o.equals("foo");
    }

    // fails
    @Test public void testExpectedFailure2() {
        Object o = null;
        o.equals("foo");
    }
}

首先,请注意第一种方法标记为@Deprecated。我将其用作要忽略任何断言失败的方法的标记。您可以做任何您想识别的方法,这只是一个例子。

接下来,在中ExpectedFailure#apply(),当我执行base.evaluate()时,我捕获了任何Throwable(包括AssertionError),并且如果该方法用@Deprecated标注,则忽略该错误。您可以执行任何逻辑,根据版本号,某些文本等来决定是否忽略该错误。您还可以将动态确定的标志传递给ExpectedFailure,以使其在某些版本号下失败:

public void unmarshalledDocumentHasExpectedValue() {
    doc = unmarshaller.unmarshal(getResourceAsStream("mydoc.xml"));

    expectedFailure.setExpectedFailure(doc.getVersionNumber() < 3000);

    final ST title = doc.getTitle();
    assertThat(doc.getTitle().toStringContent(), equalTo("Expected"));
}

有关更多示例,请参见ExternalResource和ExpectedException

忽略预期的失败测试而不是通过测试

如果要将测试标记为“已忽略”而不是“成功”,则它会变得有些复杂,因为在执行测试之前会忽略它们,因此您必须将测试追溯标记为已忽略,这将涉及构造自己的Runner。首先,请参见我对如何在套件中定义JUnit方法规则的回答。。或问另一个问题。



 类似资料:
  • 我试图在我正在编写的脚本中测试错误处理。如果异步函数fetchBar失败,我将模式匹配失败案例,然后返回包含失败结果的成功未来。 然而,当我对这个流进行单元测试时,我在测试失败案例时遇到了麻烦。我在fetchBar上打了一个存根,以返回失败的future,如下所示。 但是我注意到fetchedBar返回的是成功而不是失败。为什么会这样,我如何存根fetchBar函数来创建一个失败的尝试?

  • 我想学习如何编写JUnit测试,但我完全失败了。 这是我的测试: 问题是这个简单的断言已经失败了。返回的列表是空的。我知道,我对这一切都不熟悉,但是从我的角度来看,失败是如此出乎意料,以至于我没有办法解决这个问题。 以下是全部代码(不太多): 要测试的功能就是这个,我知道它是有效的: 实际上,我只是想学习如何编写这样的测试,但是几天来我一直没有写出来。有相当多的例子和解释,但是不管我做什么尝试,我

  • 我想测试某个异常是用作为JUnit测试方法的某个部分中的异常原因抛出的。 测试方法本身不应该抛出异常--只是它的一个特定部分。

  • 这就是我的应用程序中测试的样子: 我怎样才能避免这种行为呢?

  • Jenkins将良好的构建标记为失败,因为某些单元测试失败。如果我在没有单元测试的情况下运行构建,我将获得构建成功状态。如何配置Jenkins来执行以下操作:

  • 从Spring 3.1开始,由于@Enable*注释,我们可以更容易地使用JavaConfig。 所以我做了一个WebConfig来设置WebMvc配置,并尝试对其进行测试。但是,如果我使用WebConfig扩展WebMVCConfigureAdapter或WebMvcConfigurationSupport,单元测试将失败,因为缺少ServletContext。代码和消息如下所示。 网络配置。J