Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to write a good unit test message

I have recently started to write unit tests in my projects and I notice that all assert statements have a message argument.

What makes a good message for a unit test?

$cache->set('foo', 3);
$this->assertEquals($cache->get('foo'), 3, 'what should i say?');

Thanks!

like image 291
Venkat D. Avatar asked Dec 20 '11 03:12

Venkat D.


3 Answers

State the fact under test.

Consider:

$this->assertEquals($person->age, 21, "Age is 21")

vs.:

$this->assertEquals($person->age, 21, "Age of person born on 1990-12-20");

A good unit test message should help you quickly guess where the bug is. A bad one makes you spend more time hunting.

like image 193
holygeek Avatar answered Nov 17 '22 04:11

holygeek


I usually keep them nice and short -- just what's being tested. The message doesn't have to explain the story of all the things that could have gone wrong, it just has to point the reader in the right initial direction. The test should be clear enough that they can figure it out from there.

Generally I write my messages such that someone who isn't familiar with the test will have at least a bit of context, and someone who knows the test better will probably know exactly what went wrong (or at least where in the test something went wrong).

In the example above, I would say something like "cache for 'foo'," so that the message would come back as "cache for 'foo' expected 3 but was 67." For someone familiar with the test, that's going to be a lot more useful than "expected 3 but was 67 in line 123 of test abc."

(I'm primarily a Java developer, so I'm speaking as if this were JUnit; I assume phpunit or whatever it's called work about the same way.)

like image 42
yshavit Avatar answered Nov 17 '22 06:11

yshavit


This article makes a good case on skipping the message parameter. In summary:

  • Aim for descriptive/useful test method names (this will often remove the need for a message)
  • Aim to have one assert per test (so that the test method name can describe that single purpose)
  • Include a message as a last resort (eg. if the above cannot be adhered to)

Side note: I find that messages are good when using features like DataRows. The message helps to distinguish which DataRow may be failing. C# / VS Test example:

[TestMethod]
[DataRow(<some arguments>, <message1>)]
[DataRow(<some arguments>, <message2>)]
[DataRow(<some arguments>, <message3>)]
public void MyTest(<some params>, string message)
{
    ...
}
like image 1
datchung Avatar answered Nov 17 '22 05:11

datchung