mpm writes:
> Debugging of the applications now looks like:
> $ced->log('warn',"No price for this product")

Here's an an alternative that we've evolved from Modula-2 to C to Java
to Perl :-)  Firstly, I try to distinguish between stuff I always
want to see and debugging messages.  The former we call logging, and
wrap it in a class Bivio::IO::Alert which also outputs the source line
of the caller, time, etc. configurably.  This is very handy for
figuring out what's complaining.

The latter we call "trace" messages which is presented by
Bivio::IO::Alert, but is defined as follows:

    _trace('No price for this product') if $_TRACE;

The "if $_TRACE" is an optimization, which can be left out but avoids
the overhead of argument evaluation.

The _trace() subroutine and $_TRACE variable is dynamically generated
by our Trace module, which any package can register with as follows:

    use vars ('$_TRACE');
    Bivio::IO::Trace->register;

You can then configure tracing with two configuration values, which
also can be passed on the command line.  Here's an example:

    'Bivio::IO::Trace' => {
        package_filter => '/Bivio/ && !/PDF/',
        call_filter => '$sub ne "Bivio::Die::_new"',
    },

Here I want to see tracing from all packages with the word Bivio in
their names but not PDF, and I want to ignore individual calls from
the subroutine Bivio::Die::_new.  In practice, we rarely use the
call_filter, so from any bOP command line utility, you can say, e.g.,

    b-release install my-package --TRACE=/Release/

which translates to:

    'Bivio::IO::Trace' => {
        package_filter => '/Release/',
    },

You can set the call filter or any other configuration value from the
command line with --Bivio::IO::Trace.call_filter='$sub ne "foo"'

> We use LWP for testing.  For things like cookies and argument parsing, LWP 
> is great for regression testing.  For content, it is much harder to come 
> up with a pass/fail situation since the content can change, but still 
> possible.

You might want to check out Bivio::Test::Language::HTTP.  It parses
the incoming HTML, and allows you to write scripts like:

    test_setup('PetShop');
    home_page();
    follow_link('Dogs');
    follow_link('Corgi');
    follow_link('Female Puppy Corgi');
    add_to_cart();
    checkout_as_demo();

This particular code does a number of things including validating that
animals are getting in the cart.  Additional script language is defined in
Bivio::PetShop::Test::PetShop, which subclasses
Bivio::Test::Language::HTTP, which provides follow_link and home_page
generically.

> I haven't found a better way to do web development testing durring 
> development.  Possibly writing the test first would provide some 
> improvement since you know when you have completed the change(see XP 
> docs).

I agree.  A very important practice is unit testing, especially with
large applications.  For an alternative to Test::More and xUnit, have
a look at Bivio::Test, which allows you to write tests that look like:

Bivio::Test->unit([
    'Bivio::Type::DateTime' => [
        from_literal => [
            [undef] => [undef],
            ['2378497 9'] => ['2378497 9'],
            ['-9'] => [undef, Bivio::TypeError->DATE_TIME],
            ['Feb 29 0:0:0 MST 1972'] => ['2441377 0'],
            ['Feb 29 13:13:13 XXX 2000'] => ['2451604 47593'],
            ['1972/2/29 0:0:0'] => ['2441377 0'],
            ['2000/2/29 13:13:13'] => ['2451604 47593'],
            ['Sun Dec 16 13:47:35 GMT 2001'] => ['2452260 49655'],
        ],
        from_local_literal => [
            [undef] => [undef, undef],
            ['2378497 9'] => ['2378497 7209'],
            ['-9'] => [undef, Bivio::TypeError->DATE_TIME],
            ['Feb 29 0:0:0 MST 1972'] => ['2441377 7200'],
            ['Feb 29 13:13:13 XXX 2000'] => ['2451604 54793'],
            ['1972/2/29 0:0:0'] => ['2441377 7200'],
            ['2000/2/29 13:13:13'] => ['2451604 54793'],
        ],
    ],
]);

We can write a lot of tests very quickly with this module.  We don't
always do this, but every time we don't, we regret it and end up
writing a test anyway after figuring out that we still aren't
perfect coders. :-)

Yet another trick we use is executing a task from within emacs or on
the command line.  A "task" in bOP is what the controller executes
when a URI is requested.  For example,

    b-test task login

There are two advantages to this: 1) you don't have to restart Apache
and go to another program (browser or crawler) and 2) you get the
stack trace when something goes wrong and you can type C-c C-e (in
emacs) to go right to the error.  We added this facility recently,
because we got tired of the "internal server error" restart loops.
They slow things down tremendously, and anyway, you often want to look
at the HTML to see if some thing has changed.  The output of 'b-test
task' is the resultant HTML and any mail messages that would be sent,
which you can then search on immediately directly in emacs without
first having to say Tools -> View Source and get an inferior editor in
Mozilla or whatever.

Sorry for the long message, but, hopefully, you'll be able to read
about this all and more in my book (coming soonish :-) so I won't need
to clog the ether with this stuff.

Rob

P.S. All bOP source is available at http://www.bivio.biz/hm/download-bOP or
     can be browsed online at http://petshop.bivio.biz (look at the bottom
     of the page).


Reply via email to