I debated whether or not to post this here for a long time, because I
gather that deferred plans are somewhat of  a hot topic on this group.
 But finally I decided that I just needed to understand some history
and make sure there's nothing I'm missing here.

First, if you'll bear with me, a little background:  When I first
discovered test-first programming, via the original XP book, I thought
it was brilliant, and I started employing it on many of my projects.
However, I confess that (somewhat foolishly) I did not use Test::More
and friends to do my tests.  Instead, I rolled my own system.  Since I
have never (yet) released any of my code to CPAN, using Test::More
(and friends) was not already a habit for me.  And I thought to myself
that the testing process for installation of a module was quite
different from the testing process for developing code.  Now that I'm
considering finally getting off my lazy ass and putting some stuff out
to CPAN, I realized that I had to deal with installation testing, and
I started reading everything I could about the testing frameworks of
standard Perl, TAP, etc.  My conclusions are that I still think that
installation testing is a _little_ different from development testing,
but certainly not enough to justify having my own little world of
testing libraries, most of which do exactly what Test::More et al do,
only without the benefit of nearly as much aggregated programmer time
put into making sure they're correct.  So I set out to convert my
stuff to the standard stuff.  And I only hit two real snags.

The first is that _during development_, I want to stop my tests on the
first failure.  This is the minor difference, IMHO, between
installation testing and development testing.  For installation, it
obviously makes no sense to do this.  But for development testing, it
makes sense to me.  (I understand that others may not feel so, but
I've also noticed that some on this list agree.)  When I first began
this effort, there wasn't really a solution for me on CPAN, but now
that Ovid has released the excellent Test::Most, that particular itch
is scratched, so I don't really want to open that can of worms again.

The second sticking point is the concept of plans, and here is where I
really want to understand the reasoning behind it.  My understanding
is that a plan has one primary function: to insure that if a test
script dies before all the tests are run, that is recognized as an
error.  Now, in my own test scripts, I achieved this via a very simple
methodology: all my scripts ended with a simple print statement: "ALL
DONE".  I ran the script, and if I saw my ALL DONE at the end, the
script was fine.  If I didn't, I obviously had a problem.  Very
simple, very clean.  My implementation was a bit simplistic, perhaps,
but no matter how much I've read about testing in Perl, I still can't
see why the idea itself isn't sound.

This idea is similar to what Ovid has been calling "deferred plans",
except that he has been suggesting that the _number_ of tests be
submitted to the test harness at the end, whereas I'm just talking
about a success flag.  Now, in the original discussion back in
November, Adrian Howard asked:

> I don't get this. Why is saying "I know this test script outputs test 
> results" at the start better than saying it at the end?

And Aristotle answered:

> So you'd defer the plan in cases where the number of tests is
> predetermined but maybe hard to precompute, or where it's
> variable. So in both cases you are calculating the number at run
> time, which is immediately subject to more bugs than providing a
> constant.
>
> Additionally, it's more likely for a bug in the calculation to
> line up with a bug in the corresponding test code, so that you
> end up with a plan that matches the number of tests run even
> though you *intended* to run fewer/more tests.
>
> And lastly, even a runtime-calculated predeclared plan separates
> the test code and calculation code at least in time (while
> running) and probably also in space (in the source code).
> Therefore it seems to me that bugs are somewhat less likely
> to line up.

Now, I have a great respect for Aristotle (actually, I have a great
respect for all the people on this list with whose work I have any
previous experience), but it seems to me that all these objections
relate to presenting a number at the end of the tests.  My method
inherently avoids those issues.

And I don't want to defer the plan because the number of tests is hard
to predetermine, or because it's indeterminate.  I just think that
having code where every time you change things in one place, you have
to make sure you change something somewhere else isn't a good thing.
In any other programming scenario, I think most everyone would agree
with me.  But when it comes to testing, doing this in terms of tests
is not only okay, it's considered best practice.

So I guess I'm looking for enlightenment.  I can't help but feel like
there's something I'm missing.  If the only function of a test plan is
to make sure all the tests are run, my method handles that, and it's
simpler and requires less bookkeeping.  And if there are other
functions of the test plan, I'm just not seeing what they are.  But
I'm not so arrogant as to believe that no one's ever considered my
method before either.  So I'm hoping that someone here can show me the
light.

Not criticizing, not claiming my method is better, just looking for
any reasons why this wouldn't work.  And, JIC there's some agreement
that it _would_ work, I've already put together a patch for Test::Most
that does it.  That is, at the top of your script, you put this:

        use Test::Most 'defer_plan';

and at the bottom of your script, you put this:

        all_done();

and it just DTRT.  The implementation is perhaps not as clean as I'd
like it to be, but it's not a horrific hack either.  I'm going to
forward it to Ovid through normal CPAN channels.

Thoughts?


        -- Buddy

Reply via email to