Stories
Slash Boxes
Comments
NOTE: use Perl; is on undef hiatus. You can read content, but you can't post it. More info will be forthcoming forthcomingly.

All the Perl that's Practical to Extract and Report

use Perl Log In

Log In

[ Create a new account ]

schwern (1528)

schwern
  (email not shown publicly)
http://schwern.net/
AOL IM: MichaelSchwern (Add Buddy, Send Message)
Jabber: schwern@gmail.com

Schwern can destroy CPAN at his whim.

Journal of schwern (1528)

Thursday September 09, 2010
03:15 AM

Test::Builder2 at 10k Feet

[ #40527 ]

Here's a diagram of the "flow" of assert results through Test::Builder version 1.

                     .-------.
                     | foo.t |
                     '-------'
                         |
                         |
     .-------------.     |     .----------------.
     | Test::More  |<--------->| Test::Whatever |
     '-------------'           '----------------'
            |                           |
            |                           |
            |                           |
            |     .---------------.     |
            '---->| Test::Builder |<----'
                  '---------------'
                          |
                          v
                       .-----.
                       | TAP |
                       '-----'
                          |
                          v
                  .---------------.
                  | Test::Harness |
                  '---------------'

You write foo.t using Test::More and Test::Whatever. These both
use the same Test::Builder object. It spits out TAP which
Test::Harness converts into something human readable.

The big problem there is Test::Builder is monolithic. There's no
further breakdown of responsibilities. It only spits out TAP, and
only one version of TAP.

Here's what Test::Builder2 looks like:

                                  .-------.
                 .----------------| foo.t |-------------------.
                 |                '-------'                   |
                 |                    |                       |
                 |                    |                       |
                 v                    v                       v
          .------------.     .----------------.     .------------------.
          | Test::More |     | Test::Whatever |     | Test::NotUpdated |
          '------------'     '----------------'     '------------------'
                 |                    |                       |
                 |                    v                       v
                 |           .----------------.       .---------------.
                 '---------->| Test::Builder2 |<------| Test::Builder |
                             '----------------'       '---------------'
                                      |
                                      v
           .--------------.    .-------------.
           | TB2::History |<---| TB2::Result |
           '--------------'    '-------------'
                                      |
                                      |
    .--------------------------.      |       .---------------------.
    | TB2::Formatter::TAP::v13 |<-----'------>| TB2::Formatter::GUI |
    '--------------------------'              '---------------------'
                  |                                      |
                  v                                      |
  .-------------------------------.                      |
  | TB2::Formatter::Streamer::TAP |                      |
  '-------------------------------'                      |
                  |                                      |
                  v                                      |
               .-----.                                   |
               | TAP |                                   |
               '-----'                                   |
                  |                                      |
                  v                                      v
          .---------------.                     .-----------------.
          | Test::Harness |                     | Pretty Pictures |
          '---------------'                     '-----------------'

It starts out the same, foo.t uses a bunch of test modules
including Test::More and Test::Whatever using the same Test::Builder2
object, but it also uses Test::NotUpdated which is still using
Test::Builder. That's ok because Test::Builder has been rewritten in
terms of Test::Builder2 (more on that below).

Test::Builder2, rather than being a monolith, produces a
Test::Builder2::Result object for each assert run. This gets stored
in a Test::Builder2::History object for possible later use. It also
gets handed to a Test::Builder2::Formatter object, the default is
Test::Builder2::TAP::v13 which produces TAP version 13. This is fed
to a Streamer that prints it to STDOUT and STDERR which is read by
Test::Harness and made human readable.

Because Test::Builder2 is not monolithic, you can swap out parts. For
example, instead of outputting TAP it could instead hand results to a
formatter that produced a simple GUI representation, maybe a green
bar, or something that hooks into a larger GUI. Or maybe one that
produces JUnit XML.

Here's how Test::Builder and Test::Builder2 Relate.

        .-----.                                         .-----.
        | TB2 |                                         | TB1 |
        '-----'                                         '-----'
           |                                               |
           |                                               |
           |                                               |
           |                                               |
           v                                               v
    .-------------.        .--------------.         .-------------.
    | TB2::Result |------->| TB2::History |<--------| TB2::Result |
    '-------------'        '--------------'         '-------------'
           |                                               |
           |                                               |
           |                                               |
           |              .----------------.               |
           '------------->| TB2::Formatter |<--------------'
                          '----------------'
                                   |
                                   v
                              .--------.
                              | Output |
                              '--------'

Test::Builder and Test::Builder2 coordinate their actions by sharing
the same History and Formatter objects. If you call TB1->ok() it
produces a Result object which it hands to the History singleton and
the Formatter singleton. If you call TB2->ok() it produces a Result
object which it hands to the same History and Formatter objects.

This allows most of the Test::Builder code to remain the same while
still coordinating with Test::Builder2. It also allows radically
different builders to be made without Test::Builder2 dictating how
they're to work.

The downside is that roles applied to Test::Builder2 will not effect
Test::Builder. Because of this, Test::Builder may become more closely
coupled with Test::Builder2 in the future.

Diagrams by App::Asciio.

The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
 Full
 Abbreviated
 Hidden
More | Login | Reply
Loading... please wait.