Provided by: libtest-bdd-cucumber-perl_0.17-1_all bug

NAME

       Test::BDD::Cucumber::Manual::Tutorial - Quick Start Guide

VERSION

       version 0.17

Introduction

       In this article we're going to jump straight in to using Test::BDD::Cucumber to build some
       simple tests for Digest, a core Perl module which provides message digests.

       We'll create a "features/" directory, and put our first test case in it,
       "features/basic.feature" in it. The contents of it are, in their entirity:

        # Somehow I don't see this replacing the other tests this module has...
        Feature: Simple tests of Digest.pm
         As a developer planning to use Digest.pm
         I want to test the basic functionality of Digest.pm
         In order to have confidence in it

         Background:
           Given a usable Digest class

         Scenario: Check MD5
           Given a Digest MD5 object
           When I've added "foo bar baz" to the object
           And I've added "bat ban shan" to the object
           Then the hex output is "bcb56b3dd4674d5d7459c95e4c8a41d5"
           Then the base64 output is "1B2M2Y8AsgTpgAmY7PhCfg"

         Scenario: Check SHA-1
           Given a Digest SHA-1 object
           When I've added "<data>" to the object
           Then the hex output is "<output>"
           Examples:
             | data | output   |
             | foo  | 0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33 |
             | bar  | 62cdb7020ff920e5aa642c3d4066950dd1f01f4d |
             | baz  | bbe960a25ea311d21d40669e93df2003ba9b90a2 |

         Scenario: MD5 longer data
           Given a Digest MD5 object
           When I've added the following to the object
             """
             Here is a chunk of text that works a bit like a HereDoc. We'll split
             off indenting space from the lines in it up to the indentation of the
             first \"\"\"
             """
           Then the hex output is "75ad9f578e43b863590fae52d5d19ce6"

       This is a complete test, and if you run pherkin against it, you will get sane output! It
       just doesn't do anything ... yet.

       In the "features/" we'll add a "step_definitions/" directory, and add our first (and
       again, only) step definitions "features/step_definitions/basic_steps.pl" file in it:

        #!perl

        use strict;
        use warnings;

        use Test::More;
        use Test::BDD::Cucumber::StepFile;
        use Method::Signatures;

        Given qr/a usable (\S+) class/, func ($c) { use_ok( $1 ); };
        Given qr/a Digest (\S+) object/, func ($c) {
           my $object = Digest->new($1);
           ok( $object, "Object created" );
           $c->stash->{'scenario'}->{'object'} = $object;
        };

        When qr/I've added "(.+)" to the object/, func ($c) {
           $c->stash->{'scenario'}->{'object'}->add( $1 );
        };

        When "I've added the following to the object", func ($c) {
           $c->stash->{'scenario'}->{'object'}->add( $c->data );
        };

        Then qr/the (.+) output is "(.+)"/, func ($c) {
           my $method = {base64 => 'b64digest', 'hex' => 'hexdigest' }->{ $1 } ||
               do { fail("Unknown output type $1"); return };
           is( $c->stash->{'scenario'}->{'object'}->$method, $2 );
        };

       When you run pherkin or the Test::Builder-based test which does the same thing
       ("900_run_features.thttps://github.com/sheriff/test-bdd-cucumber-perl/blob/master/t/900_run_features.t"
       in t), we look for a "features/" directory, and search for step definitions files (matched
       by "*_steps.pl") and feature files (matched by "*.feature").

       The step matchers (the code that starts with "Given", "When" and "Then") are all loaded,
       and then we execture the feature files one by one. Let's step through the feature file,
       and look at how it matches up to the step definitions file.

Name and conditions of satisfaction

        Feature: Simple tests of Digest.pm
         As a developer planning to use Digest.pm
         I want to test the basic functionality of Digest.pm
         In order to have confidence in it

       The first non-comment line of your feature file is a description of what you intend to do.
       You need to start the name itself with the string "Feature:", and that should be the first
       line of your file, save comments (denoted by #).

       Anything after that before the next new-line are your conditions of satisfaction. These
       aren't parsed, they're treated as human-readable text, and by convention, they're a user
       story <http://en.wikipedia.org/wiki/User_story>.

Background

         Background:
           Given a usable Digest class

       Next up, we have the Background section. The Background is a special kind of Scenario that
       doesn't have an explicit name, and should occur only once in your feature file. Its steps
       are run before the steps of every other scenario - the harnesses distributed with this
       distro won't display the Background section separately, they'll just subsume the steps in
       to the other scenarios.

       This is matched by:

        Given qr/a usable (\S+) class/, func ($c) { use_ok( $1 ); };

       "Given()" is a function exported by Test::BDD::Cucumber::StepFile that accepts two
       arguments: a regular expression (or a string when you don't need to do any smart matching)
       and a coderef. We use Method::Signatures to save some typing here, so note that written
       longer hand, the above might be written:

        Given(
            qr/a usable (\S+) class/,
            sub {
               my $c = shift;
               use_ok( $1 );
            };
        );

       If you're paying attention, you might notice that "use_ok" comes from Test::More. Each
       step is run, from a Test::Builder perspective, as its own distinct test file. This happens
       seamlessly, so you can use any Test::Builder-based testing tools in your step definitions
       without really worrying about it. There's some more detail in
       Test::BDD::Cucumber::Manual::Steps.

The First Scenario...

         Scenario: Check MD5
           Given a Digest MD5 object
           When I've added "foo bar baz" to the object
           And I've added "bat ban shan" to the object
           Then the hex output is "bcb56b3dd4674d5d7459c95e4c8a41d5"
           Then the base64 output is "1B2M2Y8AsgTpgAmY7PhCfg"

       The first scenario is delimited from the previous steps by a blank line, and it's called
       Check MD5. Scenarios are marked out using the "Scenario:" keyword, and just like the
       Background section before, it's a series of steps.  These steps rely on the step before,
       which means we can examine the Test::Builder::StepContext object $c a little more closely.

        Given qr/a Digest (\S+) object/, func ($c) {
           my $object = Digest->new($1);
           ok( $object, "Object created" );
           $c->stash->{'scenario'}->{'object'} = $object;
        };

       Creates a step definition. We create a new Digest object, and then use Test::More's "ok()"
       function to check that worked. We then put it in the stash for other steps to use. There
       are three stashes documented in Test::Builder::StepContext, "feature", "scenario" and
       "step". As you might expect, "feature" is available to all step definitions that are being
       executed as part of a feature, and "scenario" is available to all steps that are being
       executed as part of a feature.

       The context is the single argument that gets passed to each step, and it contains
       evertything that step should need to execute. We'll be looking at some of the methods you
       can call against it as we look at other steps, and you can find complete documentation for
       it here: Test::Builder::StepContext.

       This scenario also introduce several ways of starting a step, Given, When, and Then, as
       well as And. These are used to organize steps by type, with Given tending to describe
       setup steps, When describing the key actions that you're testing, and Then describing the
       outputs you're looking for. You can find more on this here:
       <https://github.com/cucumber/cucumber/wiki/Given-When-Then>.

       A step definition you've declared with Given will not match a step starting with Then. You
       can use the keyword Step to declare general matching steps in your step definition files,
       although it's considered bad practice.

       Finally, the keywords And and But are simply replaced with the verb on the line before
       them.

Scenario Outlines

         Scenario: Check SHA-1
           Given a Digest SHA-1 object
           When I've added "<data>" to the object
           Then the hex output is "<output>"
           Examples:
             | data | output   |
             | foo  | 0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33 |
             | bar  | 62cdb7020ff920e5aa642c3d4066950dd1f01f4d |
             | baz  | bbe960a25ea311d21d40669e93df2003ba9b90a2 |

       The next scenario adds one of the three ways you can provide structured data to your
       steps, using placeholders and a table. This scenario is run three times, one for each
       table row, and with the " <placeholders" > being replaced by the appropriate row's column.
       These are called Scenario Outlines <https://github.com/cucumber/cucumber/wiki/Scenario-
       outlines>.

Multiline Step Arguments

         Scenario: MD5 longer data
           Given a Digest MD5 object
           When I've added the following to the object
             """
             Here is a chunk of text that works a bit like a HereDoc. We'll split
             off indenting space from the lines in it up to the indentation of the
             first \"\"\"
             """
           Then the hex output is "75ad9f578e43b863590fae52d5d19ce6"

       While before we were looking at structured data on a Scenario level, we can also provide
       it on a Step level, in two ways. Firstly, we can provide multi-line strings, as above,
       using a feature that is syntactically similar to "pystring"s, and conceptually similar to
       HEREDOCs. The contents of the string will be available to the step definition via the
       "data()" method of the context:

        When "I've added the following to the object", func ($c) {
           $c->stash->{'scenario'}->{'object'}->add( $c->data );
        };

       While we don't have an example of it here, you can also provide tables to your steps,
       which will also be available via "data()":

        Scenario: Sort Employees
          Given a set of employees
            | name  | wage   | hair color |
            | Peter | 10,000 | brown      |
            | John  | 20,000 | blond      |
            | Joan  | 30,000 | green      |

       You can find out more about these features in the Cucumber documentation here:
       <https://github.com/cucumber/cucumber/wiki/Multiline-Step-Arguments>.

Next Steps...

       That's the tutorial done! You can find out more about writing steps in
       Test::BDD::Cucumber::Manual::Steps, the documentation for our simple command-line tool in
       App::pherkin, and how to integrate with Test::Builder in
       Test::BDD::Cucumber::Manual::Integration.

AUTHOR

       Peter Sergeant "pete@clueball.com"

LICENSE

       Copyright 2011, Peter Sergeant; Licensed under the same terms as Perl