Writing Dredd Hooks In Perl
Perl hooks are using Dredd’s hooks handler socket interface. For using Perl hooks in Dredd you have to have Dredd already installed
Installation
$ cpanm Dredd::Hooks
Usage
$ dredd apiary.apib http://127.0.0.1:3000 --language=dredd-hooks-perl --hookfiles=./hooks*.pl
Note
If you’re running Dredd inside Docker, read about specifics of getting it working together with non-JavaScript hooks.
API Reference
Module Dredd::Hooks::Methods
imports following decorators:
beforeEach
,beforeEachValidation
,afterEach
wraps a function and passes Transaction object as a first argument to it
before
,beforeValidation
,after
accepts transaction name as a first argument
wraps a function and sends a Transaction object as a first argument to it
beforeAll
,afterAll
wraps a function and passes an Array of Transaction objects as a first argument to it
Refer to Dredd execution life-cycle to find when is each hook function executed.
Using Perl API
Example usage of all methods in
use Dredd::Hooks::Methods;
beforeAll( sub {
print 'before all'
});
beforeEach( sub {
print 'before each'
})
before( "Machines > Machines collection > Get Machines" => sub {
print 'before'
});
beforeEachValidation(sub {
print 'before each validation'
});
beforeValidation( "Machines > Machines collection > Get Machines" => sub {
print 'before validations'
});
after( "Machines > Machines collection > Get Machines" => sub {
print 'after'
});
afterEach( sub {
print 'after_each'
});
afterAll( sub {
print 'after_all'
});
Examples
How to Skip Tests
Any test step can be skipped by setting skip
property of the transaction
object to true
.
use Dredd::Hooks::Methods;
use Types::Serialiser;
before("Machines > Machines collection > Get Machines" => sub {
my ($transaction) = @_;
$transaction->{skip} = Types::Serialiser::true;
});
Sharing Data Between Steps in Request Stash
If you want to test some API workflow, you may pass data between test steps using the response stash.
use JSON;
use Dredd::Hooks::Methods;
my $response_stash = {};
after("Machines > Machines collection > Create Machine" => sub {
my ($transaction) = @_;
# saving HTTP response to the stash
$response_stash->{$transaction->{name}} = $transaction->{real}
});
before("Machines > Machine > Delete a machine" => sub {
my ($transaction) = @_;
#reusing data from previous response here
my $parsed_body = JSON->decode_json(
$response_stash->{'Machines > Machines collection > Create Machine'}
);
my $machine_id = $parsed_body->{id};
#replacing id in URL with stashed id from previous response
$transaction->{fullPath} =~ s/42/$machine_id/;
});
Failing Tests Programmatically
You can fail any step by setting fail
property on transaction
object to true
or any string with descriptive message.
use Dredd::Hooks::Methods;
before("Machines > Machines collection > Get Machines" => sub {
my ($transaction) = @_;
$transaction->{fail} = "Some failing message";
});
Modifying Transaction Request Body Prior to Execution
use JSON;
use Dredd::Hooks::Methods;
before("Machines > Machines collection > Get Machines" => sub {
my ($transaction) = @_;
# parse request body from API description
my $request_body = JSON->decode_json($transaction->{request}{body});
# modify request body here
$request_body->{someKey} = 'some new value';
# stringify the new body to request
$transaction->{request}{body} = JSON->encode_json($request_body);
});
Adding or Changing URI Query Parameters to All Requests
use Dredd::Hooks::Methods;
beforeEach( sub {
my ($transaction) = @_;
# add query parameter to each transaction here
my $param_to_add = "api-key=23456";
if ($transaction->{fullPath} =~ m/?/){
$transaction->{fullPath} .= "&$param_to_add";
} else {
$transaction->{fullPath} .= "?$param_to_add";
}
});
Handling sessions
use JSON;
use Dredd::Hooks::Methods;
my $stash = {}
# hook to retrieve session on a login
after('Auth > /remoteauth/userpass > POST' => sub {
my ($transaction) = @_;
my $parsed_body = JSON->decode_json($transaction->{real}{body});
my $stash->{token} = $parsed_body->{sessionId};
)};
# hook to set the session cookie in all following requests
beforeEach( sub {
my ($transaction) = @_;
if (exists $stash->{token}){
$transaction->{request}{headers}{Cookie} = "id=".$stash{token};
}
});
Remove trailing newline character in expected plain text bodies
use Dredd::Hooks::Methods;
beforeEach(
my ($transaction) = @_;
if( $transaction->{expected}{headers}{Content-Type} eq 'text/plain'){
$transaction->{expected}{body} = chomp($transaction->{expected}{body});
}
});