NAME
Test::Cucumber::Tiny - Cucumber-style testing in perl
SYNOPSIS
Cucumber is a tool that executes plain-text functional descriptions as automated tests. The language that Cucumber understands is called Gherkin.
While Cucumber can be thought of as a "testing" tool, the intent of the tool is to support BDD. This means that the "tests" are typically written before anything else and verified by business analysts, domain experts, etc. non technical stakeholders. The production code is then written outside-in, to make the stories pass.
USAGE
If you need to shared the scenarios with the business analysts.
Write the scenarios in YAML
use Test::More tests => 1;
use Test::Cucumber::Tiny;
subtest "Feature Test - Calculator" => sub {
## In order to avoid silly mistake
## As a math idiot
## I want to be told a sum of 2 numbers
## Here is an example using YAML file:
my $cucumber = Test::Cucumber::Tiny->ScenariosFromYAML( "t/test_functions/something_something.yml" );
## Here is an example using a list:
my $cucumber = Test::Cucumber::Tiny->Scenarios(
{
Scenario => "Add 2 numbers",
Given => [
"first, I entered 50 into the calculator",
"second, I entered 70 into the calculator",
],
When => [ "I press add", ],
Then => [ "The result should be 120 on the screen", ]
}, {
Scenario => "Add numbers in examples",
Given => [
"first, I entered <1st> into the calculator",
"second, I entered <2nd> into the calculator",
],
When => [ "I press add", ],
Then => [ "The result should be <answer> on the screen", ],
Examples => [
{
'1st' => 5,
'2nd' => 6,
answer => 11,
}, {
'1st' => 100,
'2nd' => 200,
answer => 300,
}
],
}, {
Scenario => "Add numbers using data",
Given => [
{
condition => "first, I entered number of",
data => 45,
}, {
condition => "second, I entered number of",
data => 77,
}
],
When => [ "I press add", ],
Then => [
{
condition => "The result is",
data => 122,
}
],
}
);
$cucumber->Given( qr/^(.+),.+entered (\d+)/ => sub {
my $c = shift;
my $subject = shift;
my $key = $1;
my $num = $2;
$c->{$key} = $num;
$c->Log( $subject );
})
->Given( qr/^(.+),.+entered number of/ => sub {
my $c = shift;
my $subject = shift;
my $key = $1;
$c->{$key} = $c->{data};
})
->When( qr/press add/ => sub {
my $c = shift;
my $subject = shift;
$c->{answer} = $c->{first} + $c->{second};
})
->Then( qr/result.+should be (\d+)/ => sub {
my $c = shift;
my $subject = shift;
my $expected = $1;
is $c->{answer}, $expected, $subject;
})
->Then( qr/result is/ => sub {
my $c = shift;
my $subject = shift;
is $c->{data}, $c->{answer}, $subject;
})
->Test;
};
METHODS
new
Create a cucumber for test
Test::Cucumber::Tiny->new(
scenarios => [
{
....
}
]
)
->Given(...)
->Then(...)
->Test;
Scenarios
Create a cucumber with a plain array list of scenarios
Test::Cucumber::Tiny->Scenarios(
{
....
}
)
->Given(...)
...
->Then(...)
->Test;
ScenariosFromYML
Create a cucumber from a YAML file.
YMAL Example:
- Scenario: Add 2 numbers
Given:
- first, I entered 50 into the calculator
- second, I entered 70 into the calculator
When: I press add
Then: The result should be 120 on the screen
- Scenario: Add 3 numbers
Given:
- first, I entered 50 into the calculator
- second, I entered 70 into the calculator
- third, I entered 10 into the calculator
When: I press add
Then: The result should be 130 on the screen
In Code:
my $cuc = Test::Cucumber::Tiny->ScenariosFromYML( "scenarios.yml" );
$cuc->Given(...);
...
$cuc->Then(...);
$cuc->Test;
Before
@param regexp
@code ref
Given
@param regexp
@param code ref
When
@param regexp / hashref { regexp, data }
@param code ref
Then
@param regexp / hashref { regexp, data }
@param code ref
Any
Use any to set all 3 like below
->Any( qr/.+/ => sub { return 1 } );
Same as
->Before( qr/.+/ => sub { return 1 } );
->Given( qr/.+/ => sub { return 1 } );
->When( qr/.+/ => sub { return 1 } );
->Then( qr/.+/ => sub { return 1 } );
->After( qr/.+/ => sub { return 1 } );
After
@param regexp
@code ref
NextStep
When you are the functions of Given
Call NextStep will jump to When
When you are the functions of When
Call NextStep will jump to Then
When you are the functions of Then
Call NextStep will finish the current scenario.
NextExample
When you are the functions of Given, When or Then
Call NextExample will finish the current cycle and use the next example data in the current scenario.
NextScenario
Just jump to the next scenario.
Test
Start Cucumber to run through the scenario.
Log
To use different Test verbose methods like diag, note or explain
To set the method by
export CUCUMBER_VERBOSE=diag
or
$ENV{CUCUMBER_VERBOSE} = "diag";
or
...::Tiny->new( verbose => "diag" );
By default the method is "explain"
usage
$cucumber->Log( "here" );
$cucumber->Given(qr/.+/ => sub {
my $c = shift;
$c->Log( "Test" );
});
BUILTIN STEPS
debugger
Use debugger in any steps with perl -d
that will stop to the point when reached.
e.g.
Test::Cucumber::Tiny->Scenarios(
{
Given => "a clild a book",
When => "he opens the book",
Then => [
"debugger", ## <---- STOP here when run with perl -d test.t
"he will find the bookmark",
]
}
);
BUILTIN DATA POINTS
$c
Scenario wide stash, each scenario has it own one.
any step subref the first arguments will be a hashref
e.g.
$cucumber->Given( qr/.+/ => sub {
my $c = shift; ## it is a hashref
my $subject = shift; ## The subject of the step
$c->Log( $subject );
});
$c->{FEATURE_WIDE}
Feature wide stash, all scenarios shared the same one.
you can reach it inside the scenario stash by FEATURE_WIDE key
e.g.
$cucumber->Given( qr/.+/ => sub {
my $c = shift;
my $subject = shift;
my $f = $c->{FEATURE_WIDE}; ## A readonly HashRef
$f->{something_here} = 1;
$c->Log( $subject );
});
$c->{Scenario}
The subject you set for that scenario
e.g.
$cucumber->Given( qr/.+/ => sub {
my $c = shift;
$c->Log( $c->{Scenario} );
});
$c->{Step}
The subject you set for the current step
e.g.
$cucumber->Given( qr/.+/ => sub {
my $c = shift;
$c->Log( $c->{Step} );
});
$c->{data}
The current running step sample data
e.g.
...::Tiny->Scenarios(
{
Given => {
condition => "...",
data => "ANYTHING HERE",
}, ...
}
)
->Given( qr/.+/ => sub {
my $c = shift;
my $anything_here = $c->{data};
});
$c->{Example}
The current running example
$c->{Examples}
All the examples in the current scenario
e.g.
...::Tiny->Scenarios(
{
Given => "... <placeholder>",
Examples => [
{
placeholder => "foobar",
},
{
placeholder => "sample",
}
]
}
)
->Given( qr/.+/ => sub {
my $c = shift;
my $examples = $c->{data};
});