The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

Test::Pod::Snippets - Generate tests from pod code snippets

SYNOPSIS

    use Test::Pod::Snippets;

    my $tps = Test::Pod::Snippets->new();
    $tps->generate_snippets( @pm_and_pod_files );

DESCRIPTION

Fact 1

In a perfect world, a module's full API should be covered by an extensive battery of testcases neatly tucked in the distribution's t/ directory. But then, in a perfect world each backyard would have a marshmallow tree and postmen would consider their duty to circle all the real good deals in pamphlets before stuffing them in your mailbox. Obviously, we're not living in a perfect world.

Fact 2

Typos and minor errors in module documentation. Let's face it: it happens to everyone. And while it's never the end of the world and is prone to rectify itself in time, it's always kind of embarassing. A little bit like electronic zits on prepubescent docs, if you will.

Test::Pod::Snippets's goal is to address those issues. Quite simply, it extracts verbatim text off pod documents -- which it assumes to be code snippets -- and generate test files out of them.

HOW TO USE TEST::POD::SNIPPETS IN YOUR DISTRIBUTION

If you are using Module::Build, add the following to your Build.PL:

  my $builder = Module::Build->new(
    # ... your M::B parameters
    PL_files  => { 'script/test-pod-snippets.PL' => q{}  },
    add_to_cleanup      => [ 't/pod-snippets-*.t' ],
  );

Then create the file script/test-pod-snippets.PL, which should contains

    use Test::Pod::Snippets;

    my $tps = Test::Pod::Snippets->new;

    $tps->generate_snippets( qw#
        lib/your/module.pm
        lib/your/documentation.pod
    #);

And you're set! Running Build should now generate one test file for each given module.

If you prefer to generate the tests yourself, skip the modifications to Build.PL and call test-pod-snippets.PL from the distribution's main directory.

SYNTAX

By default, Test::Pod::Snippets considers all verbatim pod text to be code snippets. To tell T::P::S to ignore subsequent pieces of verbatim text, add a =for test ignore to the pod. Likely, to return to the normal behavior, insert =for test. For example:

    A sure way to make your script die is to do:

    =for test ignore

        $y = 0; $x = 1/$y;

    The right (or safe) way to do it is rather:

    =for test

        $y = 0; $x = eval { 1/$y };
        warn $@ if $@;

=for test and =begin test ... =end test can also be used to add code that should be include in the tests but not in the documentation.

Example:

    The right way to do it is:

        $y = 0; $x = eval { 1/$y };

        =for test
           # make sure an error happened
           is $x => undef;
           ok length($@), 'error is reported';

METHODS

new( %options )

Creates a new Test::Pod::Snippets object. The method accepts the following options:

extract_verbatim_bits => $boolean

If set to true, extracts all verbatim text from the pod.

Set to true by default.

extract_functions => $boolean

If set to true, extracts function definitions from the pod. More specifically, Test::Pod::Snippets looks for a pod section called FUNCTIONS, and assumes the title of all its direct subsections to be functions.

For example, the pod

    =head1 FUNCTIONS

    =head2 play_song( $artist, $song_title )

    Play $song_title from $artist.

    =head2 set_lighting( $intensity )

    Set the room's light intensity (0 is pitch black 
    and 1 is supernova white, -1 triggers the stroboscope).

would generate the code

    @result = play_song( $artist, $song_title );
    @result = set_lightning( $intensity );

Pod markups are automatically stripped from the headers.

extract_methods => $boolean

Same as extract_functions, but with methods. In this case, Test::Pod::Snippets looks for a pod section called METHODS. The object used for the tests is assumed to be '$thingy', and its class to be given by the variable '$class'.

For example, the pod

    =head1 METHODS

    =for test
        $class = 'Amphibian::Frog';

    =head2 new( $name )

    Create a new froggy!

    =head2 jump( $how_far )

    Make it jumps.

will produces

    $class = 'Amphibian::Frog';
    $thingy = $class->new( $name );
    @result = $thingy->jump( $how_far );

generate_snippets

    $tps->generate_snippets( @source_files )

For each file in @source_files, extracts the code snippets from the pod found within and create the test file t/code-snippets-xx.t.

extract_snippets

    $test_script = $tps->extract_snippets( $file )

Returns the code of a test script containing the code snippets found in $file.

AUTHOR

Yanick Champoux, <yanick at cpan.org>

BUGS

Please report any bugs or feature requests to bug-test-pod-snippets at rt.cpan.org, or through the web interface at http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Test-Pod-Snippets. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.

SUPPORT

You can find documentation for this module with the perldoc command.

    perldoc Test::Pod::Snippets

You can also look for information at:

SEE ALSO

pod2snippets

Test::Inline

Whereas Test::Pod::Snippets extracts tests out of the modules' documentation, Adam Kennedy's Test::Inline allows to insert tests within a module, side-by-side with its code and documentation.

For example, the following code using Test::Pod::Snippets

    =head2 shout()

    Shoutify the passed string.

        # set $x to 'CAN YOU HEAR ME NOW?'
        my $x = shout( 'can you hear me now?' );

        =for test
        is $x => 'CAN YOU HEAR ME NOW?';

is equivalent to this code, using Test::Inline:

    =head2 shout()

    Shoutify the passed string.

        # set $x to 'CAN YOU HEAR ME NOW?'
        my $x = shout( 'can you hear me now?' );

    =begin testing
    my $x = shout( 'can you hear me now?' );
    is $x => 'CAN YOU HEAR ME NOW?';
    =end testing

COPYRIGHT & LICENSE

Copyright 2006, 2007 Yanick Champoux, all rights reserved.

This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.