Junit4: assertTrue()/assertFalse() should include an error message by default

Created on 10 Nov 2014  ·  16Comments  ·  Source: junit-team/junit4

assertTrue(falseMethod()) gives:
junit.framework.AssertionFailedError
assertEquals(true, falseMethod()) gives:
junit.framework.AssertionFailedError: expected: but was:

Can we add default error messages for assertTrue(boolean)/assertFalse(boolean)?

The easiest thing to do is probably just to call assertEquals(true, condition), etc.

Most helpful comment

You can provide a message to assertTrue and assertFalse.

assertTrue("The user is not happy, but she should.", user.isHappy());
assertFalse("The user is sad, but she should not.", user.isSad());

This message is shown in the stack trace.

java.lang.AssertionError: The user is not happy, but she should.
java.lang.AssertionError: The user is sad, but she should not.

All 16 comments

Would such default error messages be helpful? You'd have to look at the test code to figure out what went wrong anyway, wouldn't you?

BTW Please use org.junit.Assert instead of junit.framework.Assert.

Let's say I write this test:

User user = ...;
assertTrue(user.isHappy());
assertFalse(user.isSad());

The test fails with an AssertionError with no message. There's no way to tell without inspecting the code and inspecting line numbers which assertion failed.

Why is more data a bad thing?

More data is not a bad thing. In this case, I can only see a tiny bit of more data, though.

While I'm not against this feature request, I think there a better ways to formulate assertions nowadays, e.g. Hamcrest or Truth.

Nevertheless, I think if someone would submit a pull request for this issue, we would probably merge it... ;-)

@junit-team/junit-committers Any objections?

I certainly don't disagree with that :-)
https://github.com/google/truth/commits?author=kluever

But we've had some folks at Google who were reluctant to use assertTrue/assertFalse because of this. But sure, I'll send a pull request for this.

:smile:

You can provide a message to assertTrue and assertFalse.

assertTrue("The user is not happy, but she should.", user.isHappy());
assertFalse("The user is sad, but she should not.", user.isSad());

This message is shown in the stack trace.

java.lang.AssertionError: The user is not happy, but she should.
java.lang.AssertionError: The user is sad, but she should not.

@stefanbirkner Yes, I'm well aware of that, but why not show a reasonable error message for the default case too?

We already do this for assertEquals(expected, actual)...this is so you don't have to write:
assertEquals("Expected " + expected +" but was " + actual, expected, actual);

While I agree having a better message for a failure from assertTrue() could be useful, I am not sure if "expected <true> but was <false>" is better

I believe @dsaff had some historical context.

Just to be clear about the scope of the problem: "Expected but was " is 'much better' because of a stylistic preference for some message rather than none, not because it conveys actual additional information, correct?

The original design thought was that making up an error message is a cognitive distraction from the matter at hand. If I say assertTrue(list.isEmpty()), I'm thinking of the state of list, not of a comparison test between booleans. Thus, JUnit has nothing useful to say, and should say nothing.

That's the reason behind Chesterton's fence.

There's still no really interesting data given in this case mentioned above:

assertTrue(user.isHappy());
assertFalse(user.isSad());

The reason that assertEquals has a more informative error message is because it has something more informative to say, namely what the actual value and expected values _are_, which are often not known until runtime.

JUnit is a heavily used library, and even minor changes like this, when made to core methods, tend to break someone's test somewhere, where someone is depending on the current behavior of JUnit. I'm fine with doing that if the new behavior is different in a useful way, but I'm not convinced of the usefulness by the argument so far.

A consequence of the current state is that a number of reasonable and intelligent developers have a personal practice of always writing assertEquals(true, expression()) instead of assertTrue(expression()). Plus, of course, asking reviewees to do the same, putting it in their style guides, etc. This makes us sad, because we like code simplicity, but I don't think we can claim that that number is very high.

I also think the answer to David's opening question (last comment) is a clear "yes". The only case in which any actual information is provided is when a test method contains exactly one messageless assertTrue and exactly one messageless assertFalse. That's not very common, _and_ there's a stack trace, _and_ they could have supplied a message... it doesn't add up to much. I think it has to do with the messageless exception just appearing too _bare._

@junit-team/junit-committers What are we going to do about this issue?

Well, I'm in favor of closing it. Kevin, Kurt, are either of you enthusiastic enough to be counsel for the defense?

I'm in favor of closing it.

I do vote up this issue. Other frameworks support showing actual value capability and it's essential. I just couldn't believe JUnit is that inflexible.

I do vote up this issue since it's important to have a more informative error message for assertTrue and assertFalse. My colleagues and I are reluctant to use assertTrue/assertFalse because of this.

@ChaminW You can use assertTrue("Some more specific message.", value); for more informative error message.

Was this page helpful?
0 / 5 - 0 ratings