35

How can I get the results of my JUnit assertions to be printed [to standard output]?

I have some tests like this:

@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());
}

This is the printed output format I am hoping to get:

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

Is there way to do this using runners and suites? Or does there exist any assertSuccess(), assertFailed() methods?

cellepo
  • 4,001
  • 2
  • 38
  • 57
Petr Přikryl
  • 1,641
  • 4
  • 22
  • 34
  • 1
    By the way, the `message` parameter is only applicable when the assertion fails, so your `assertNotNull` message should actually be "a1 does not exist" etc... – Jonathan Apr 10 '13 at 12:43
  • 6
    any particular reason why you would want this? – Olimpiu POP Apr 10 '13 at 12:53
  • 2
    Both your needs could be considered an anti-pattern in the unit testing world. Your tests should assert one thing only, so there should be no reason for wanting a non-failing assertion. Your tests should be automated with all checking being done by the asserts, so there should be no need to want a printout for manual inspection. In practice, there are good reasons for wanting the first, such as running table-driven tests and needing multiple assert calls to check one logical fact. Be wary of the second, though. Automating is the only way forward in unit and regression testing. – user7610 Jul 07 '16 at 20:31
  • Where do you see anything else you print from a Java program? That will probably guide you how/where to see printing from tests. But see [my answer](https://stackoverflow.com/a/62629643/1357094), as printing is probably what you want to do in the first place (like other comments allude to). – cellepo Jun 29 '20 at 00:34

4 Answers4

22

First, you have two issues not one. When an assertion fails, an AssertionError exception is thrown. This prevents any assertion past this point from being checked. To address this you need to use an ErrorCollector.

Second, I do not believe there is any way built in to JUnit to do this. However, you could implement your own methods that wrap the assertions:

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;
     }
}
Patze
  • 859
  • 10
  • 19
John B
  • 32,493
  • 6
  • 77
  • 98
  • 2
    shouldn't be the assertNotNull within the function be TestCase.assertNotNull ? – JoachimR Oct 20 '15 at 11:55
  • why we cannot print assertEqual statement? I am getting error. – Anupam Haldkar Jun 27 '20 at 17:55
  • @AnupamHaldkar you need to either find help in another Answer that covers the specifics of your code, or Ask a new Question with those specifics (if not already covered by an existing Question). We can't help you if you don't tell us what you are doing. It is also not clear why you think the print is not happening - it probably is happening, and you just need to figure out where it is printing to. – cellepo Jun 29 '20 at 00:11
  • @AnupamHaldkar where do you see anything else you print from a Java program? That will probably guide you how/where to see printing from tests. But see [my answer](https://stackoverflow.com/a/62629643/1357094), as printing is probably what you want to do in the first place (like other comments allude to). – cellepo Jun 29 '20 at 00:35
15

All the assertXXX methods have a form that allows for displaying a String on error:

assertNotNull("exists a2", p); // prints "exists a2" if p is null

There is no particular value in printing a message on success.

EDIT

Junit typically provides 2 forms of an assert. To follow the example above, you can test for a null value in 1 of 2 ways:

assertNotNull(p)

or

assertNotNull("my message on failure", p)

The framework will print the error messages with no other effort required by you (it's provided by the framework).

To test for exceptions you would use the following pattern:

try{
    someCall();
catch(Exception e){
    fail(): // exception shouldn't happen, use assertTrue(true) if it should
}

Again, there are versions of these methods for adding a message

Check the API

Romski
  • 1,912
  • 1
  • 12
  • 27
  • Ok, so I can move message in front of assert, but how to catch if assert passed or failed to print result message? – Petr Přikryl Apr 10 '13 at 12:43
  • 1
    catch the exception as shown in my answer but if you do so, make sure to rethrow the exception (or trap it in an error collector) otherwise you will get false positives – John B Apr 10 '13 at 12:44
  • I do assertTrue("some message", assertion); and the message still does not print. – Brian Reinhold Mar 08 '17 at 20:01
  • 1
    Please do not ignore exceptions in tests. Just throw them or rethrow with more info. The `fail()` call in exception clause is problematic. Just propagate the exception... [Do not write your own catch blocks that exist only to fail a test](http://www.kyleblaney.com/junit-best-practices/) – AlikElzin-kilaka Sep 03 '17 at 05:26
  • @AlikElzin-kilaka thanks for the comment, Im surprised this answer still gets attention! I don't disagree with your comment, but would add that testing for an expected exception is part of a passing test, and so is valid. Also, there are valid uses cases for calling `fail()`. I agree that my example could be better. – Romski Sep 04 '17 at 00:14
  • It does not appear any of the possibilities in the last comment by Romski, are actually desired in this case. So the possibilities are valid, but at least a little bit out of scope here. – cellepo Jun 29 '20 at 00:02
3

One last resort option is to pair each assert with a corresponding System.out.println, though obviously that is less than ideal. Still, it will solve the problem if all else fails.

durron597
  • 31,968
  • 17
  • 99
  • 158
  • That means we have no option to check what does assertEqual() return ? that's why we are enable to print. Right? – Anupam Haldkar Jun 27 '20 at 17:57
  • @AnupamHaldkar the result of the test will show the result of any assertions - if any fail within a unit test, that individual test fails: The result of that test's success/failure is visible wherever the tests results output to (which, depending on the context of how you run your tests, could be {IDE display, log file, terminal output, standard output}). This touches a bit on whether or not a principle of one assertion per unit test is adhered to, but that is tangential here. – cellepo Jun 29 '20 at 00:08
  • @AnupamHaldkar to be clear, the answer to your two questions here is, "no, incorrect". You might need to learn about printing to standard output in general (although that is not the only place to configure/find unit test results). – cellepo Jun 29 '20 at 00:14
0

Existing Answers/Comments here contain enough info to understand how to print something based on JUnit assertions - but they also explain how doing so is probably not what you actually want to do, and is probably missing the point of running unit tests in the first place.

You should be viewing the results of the tests themselves, instead of trying to print something while you don't understand how/where to view test results themselves.

Now then how/where to view results themselves depends on how you are running your tests - you need to understand how you are running your tests, and then research how to view test results according to how you are running them. Here are a few (but not limited to) examples:

cellepo
  • 4,001
  • 2
  • 38
  • 57