如何使JUnit打印断言结果

35

如何让我的 JUnit 断言结果被打印输出到标准输出?

我的测试代码像这样:

@Test
public void test01()
{
    Position p = getPositionAt('a', 1);
    assertNotNull("a1 exists", p);
    assertNotNull("figure exists a1", p.getFigure());
    
    p = getPositionAt('a', 2);
    assertNotNull("exists a2", p);
    assertNull("figure exists a2", p.getFigure());
    
    p = getPositionAt('b', 1);
    assertNotNull("exists b1", p);
    assertNull("figure exists b1", p.getFigure());
}

这是我希望得到的打印输出格式:

a1 exists -success
figure exists a1 -success
exists a2 -success
figure exists a2 -succcess
exists b1 -succcess
figure exists b1 -failed

是否有使用runnerssuites的方法来完成此操作?或者是否存在任何assertSuccess()assertFailed()方法?


1
顺便提一下,当断言失败时,“message”参数才适用,因此您的“assertNotNull”消息实际上应该是“a1不存在”等等... - Jonathan
6
为什么你想要这个? - Olimpiu POP
2
你的需求在单元测试领域中都可以被视为反模式。你的测试应该只断言一件事情,因此不应该有想要非失败断言的理由。你的测试应该是自动化的,所有检查都应该由断言完成,因此不需要想要手动检查的打印输出。实际上,有很好的理由想要第一个需求,比如运行表驱动测试并需要多个断言调用来检查一个逻辑事实。但是要小心第二个需求。自动化是单元和回归测试的唯一前进之路。 - user7610
你在Java程序中打印的任何其他内容都可以在哪里看到?这可能会指导你如何/从哪里查看测试中的打印。但是请参见我的答案,因为打印可能是你首先想要做的事情(就像其他评论所暗示的那样)。 - cellepo
4个回答

22

首先,您有两个问题而不是一个。当一个断言失败时,会抛出一个AssertionError异常。这会阻止检查此点后的任何断言。要解决这个问题,您需要使用ErrorCollector

其次,我不认为JUnit内置了任何方法来实现这一点。但是,您可以实现自己的方法来包装这些断言:

public static void assertNotNull(String description, Object object){
     try{
          Assert.assertNotNull(description, object);
          System.out.println(description + " - passed");
     }catch(AssertionError e){
          System.out.println(description + " - failed");

        throw e;
     }
}

2
函数内部的assertNotNull不应该是TestCase.assertNotNull吗? - JoachimR
为什么我们不能打印assertEqual语句?我一直在收到错误。 - Anupam Haldkar
@AnupamHaldkar,你需要在另一个回答中找到涵盖你代码具体问题的帮助,或者如果没有现有问题涵盖这些细节,则提出新问题。如果你不告诉我们你在做什么,我们无法帮助你。同时也不清楚为什么你认为打印没有发生——它很可能已经发生了,你只需要找出它打印到哪里了。 - cellepo
@AnupamHaldkar,你在Java程序中看到其他打印内容吗?这可能会指导你如何/从哪里查看测试的打印内容。但是请参见我的答案,因为打印可能是你首先想要做的事情(就像其他评论所暗示的那样)。 - cellepo

15
所有的assertXXX方法都有一种形式,可以在出错时显示字符串:
assertNotNull("存在a2", p); // 如果p为null,则打印“存在a2”
成功时打印消息没有特别的价值。
编辑
Junit通常提供两种断言形式。按照上面的例子,您可以通过以下两种方式之一测试空值:
assertNotNull(p)
或者
assertNotNull("失败时的消息", p)
框架将打印错误消息,您无需其他努力即可完成(由框架提供)。
要测试异常,您将使用以下模式:
try{
    someCall();
catch(Exception e){
    fail(): // exception shouldn't happen, use assertTrue(true) if it should
}

同样,这些方法也有用于添加消息的版本。

查看API文档


好的,我可以将消息移动到assert之前,但是如何捕获assert是否通过或失败以打印结果消息呢? - Petr Přikryl
1
按照我的答案捕获异常,但如果这样做,请确保重新抛出异常(或在错误收集器中捕获它),否则您将得到错误的结果。 - John B
我执行了assertTrue("some message", assertion); 但是消息仍然没有打印。 - Brian Reinhold
1
请勿忽略测试中的异常。直接抛出或重新抛出带有更多信息的异常。异常子句中的 fail() 调用存在问题。请只传播异常...不要编写仅用于测试失败的自定义 catch 块 - AlikElzin-kilaka
@AlikElzin-kilaka 感谢您的评论,我很惊讶这个答案仍然受到关注!我不反对您的评论,但是我会补充说,测试预期异常是通过测试的一部分,因此是有效的。此外,调用 fail() 也有有效的用例。我同意我的示例可以更好。 - Romski
在Romski上次评论中提到的任何可能性似乎都不是在这种情况下所期望的。因此,这些可能性是有效的,但至少在这里有些超出了范围。 - cellepo

3

最后一个应急方案是将每个断言语句与相应的System.out.println配对,尽管显然这不是最理想的解决方法。但如果其他方法都失败了,这仍然可以解决问题。


这意味着我们没有选项来检查assertEqual()返回什么?这就是为什么我们无法打印的原因吗? - Anupam Haldkar
@AnupamHaldkar 测试的结果将显示任何断言的结果 - 如果单元测试中有任何失败,那么该单个测试将失败:该测试的成功/失败的结果可见于测试结果输出到的任何地方(这取决于您运行测试的上下文方式,可能是{IDE 显示、日志文件、终端输出、标准输出})。这涉及到是否遵循一个断言原则每个单元测试,但这在这里是次要的。 - cellepo
@AnupamHaldkar,针对你的两个问题,答案是“不,不正确”。你可能需要了解一般情况下如何将内容打印到标准输出(尽管这不是配置/查找单元测试结果的唯一位置)。 - cellepo

0

这里的现有答案/评论包含足够的信息,可以理解如何基于JUnit断言打印内容 - 但它们同时也解释了为什么这样做可能不是您实际想要做的事情,而且很可能没有把运行单元测试的目的放在第一位。

您应该查看测试结果本身,而不是在您不理解如何/在哪里查看测试结果本身时尝试打印内容。

那么如何/在哪里查看结果本身取决于您如何运行测试 - 您需要了解自己如何运行测试,然后研究如何查看测试结果,根据您运行测试的方式。以下是一些例子(但不限于):


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接