If you were to read the TAP grammar, you would see the following line:

test ::= status positiveInteger? description? directive?

What that means is that a test line of TAP (if you read the rest of the grammar) must have an "ok" or "not ok" bit, followed by an optional test number (in practice, it's almost always there) and a test description (the directive refers to "skip" or "todo" tests). Sadly, many people don't pay attention to the powerful benefits of the description. A bad description may as well be left off; a good description is the difference between a pile of confusing code and documentation.

This sounds strange if you're not used to writing good test descriptions, but here's what's going on. Let's first look at Test::More 's is() function:

sub is ($$;$) { my $tb = Test::More->builder; return $tb->is_eq(@_); }

The ($$;$) prototype means "pass two things in scalar context, along with an optional third thing in scalar context". So you might see a test like this:

is sreverse(17), 71;

That's because the test description is optional. More often, though, you see a test like this:

is sreverse(17), 71, 'sreverse ok';

And that might print out:

ok 1 - sreverse ok

And many programmers then pat themselves on the back thinking "job well done". But what the hell is sreverse() ? I can see that the test passed and having sreverse ok as a test name is redundant. You may as well leave the test name off! However, what if the test name looked like this?

is sreverse(17), 71, 'sreverse($scalar) should act like "scalar reverse $scalar"';

Ah hah! Now we're getting somewhere. Now the description is describing the behavior, not the boolean value of the test. We get output like this:

ok 1 - sreverse($scalar) should act like "scalar reverse $scalar"

Now I can read my test output and have an idea of what the code is supposed to do and not just whether or not the tests pass. In other words, the tests are approaching documentation, not just helping to prevent changes in behavior.

Case in point: recently I encountered some test output like this:

ok 1 - redirect ok 2 - transparent gif ok 3 - cookies ok ok 4 - log data

Can you tell what that means? Me neither. In fact, this code was a bit confusing and in the process of understanding it, I wound up rewriting the test messages similar to this:

ok 1 - If no cookies are found, we should redirect the user ok 2 - ... to a transparent gif ok 3 - ... and the cookie should have a value of 0 ok 4 - ... and the log should have default values and be marked as not valid

Which of those would you rather read as a maintenance programmer? The second version doesn't completely document what's going on, but it's a heck of a lot better than the first version. In fact, if you rewrite that as a subtest, you get this:

ok 1 - If no cookies are found, we should redirect the user ok 2 - to a transparent gif ok 3 - and the cookie should have a value of 0 ok 4 - and the log should have default values and be marked as not valid 1..4 ok 1 - click detected but no cookies present

In other words, you can skip the grouping by ellipses (...) that I used to always do and group related tests in a subtest with a descriptive name of the test case. Don't neglect those test descriptions. Even if you can perfectly understand what's going on, a well-written test description is going to be a huge benefit to any programmer coming behind you and working on the system.

Side note: if the prototype "pass things in scalar context" comments sound strange, watch the following test pass and the strange test description: