rf...@drivebuytech.com wrote: > Late to this discussion. But can somebody explain to me why in java or .net > or groovy or > ruby a programmer doesn't have to induicate the number of tests that will run before hand > but in perl he must?
Let's make something clear, Perl says nothing about this. This is TAP, a cross-language testing protocol which you can use in Java or .Net or Groovy or Ruby or whatever. Similarly, you can use xUnit style tests in Perl (see Test::Unit, but really don't). Short answer: Ask Larry. He put it there 20 years ago. The plan does two things: First, it defends against premature test exits. Since premature exit usually means it crashed, we can check the exit code of a test this isn't so important any more. Second, and more importantly, the plan allows you to test for things which *don't* happen. Consider the following print "1..2\n"; if( fork ) { print "ok\n"; } else { print "ok\n"; } Consider the case where the fork() succeeds but the child process does not run. The result will be: 1..2 ok All tests pass, but the plan is violated so it's a failure. Without a plan this sort of thing is more difficult to catch. Another example might be this: $thing->add_event_handler( Ping => sub { print "ok\n" } ); Let's say you expect $thing to handle three and only three Ping events. You can plan for that. You can plan for not getting a ping event or getting too many ping events. Without the plan this would be more difficult to handle, you'd have to do the event counting yourself. In the fork() case you'd have to implement some sort of interprocess communication. No fun. OTOH Java does a lot of threaded code so they must have some way to deal with this better than I think they do. I'm no xUnit expert. In reality, most of this kerfuffery about plans goes away once Test::Builder stops bitching when you try to run a test before declaring a plan. The "deferred plan". It allows a lot more flexibility in planning and a safer no_plan. As for xUnit vs TAP, it comes down to this: in xUnit the code being tested and the test runner are all wrapped up in the same process. In TAP they are not. This has its ups and downs. There is another key difference. In xUnit, when you fail an assert you stop the test. A passing test is one that doesn't halt. This is because xUnit has the philosophy that any data after a failing test is suspect, so why bother? In TAP we like to keep going, because that data after the fail might be useful and it would suck not to have it. TAP doesn't dictate this, but that's how TAP tests tend to be written. In xUnit a passing test suite is simply one that has no failing tests. TAP is a little more stringent. A passing test suite must have no failing tests AND must conform to the plan. This lets you test some otherwise difficult cases seen above. Anyhow, because a TAP parser is reading results from another process, and because it has little control over that process, it needs some more information to know that things went ok. If the test crashes, or exits prematurely, but all tests up to that point passed it needs to know that. In xUnit if the test crashes your whole test runner crashes. But these days a TAP parser can catch most premature exits by just looking at the exit code of the test, so the plan is less useful than it once was. -- Don't try the paranormal until you know what's normal. -- "Lords and Ladies" by Terry Prachett