APP-REST-RestTestSuite

 view release on metacpan or  search on metacpan

README  view on Meta::CPAN

Any use, modification, and distribution of the Standard or Modified
Versions is governed by this Artistic License. By using, modifying or
distributing the Package, you accept this license. Do not use, modify,
or distribute the Package, if you do not accept this license.

If your Modified Version has been derived from a Modified Version made
by someone other than you, you are nevertheless required to ensure that
your Modified Version complies with the requirements of this license.

This license does not grant you the right to use any trademark, service
mark, tradename, or logo of the Copyright Holder.

This license includes the non-exclusive, worldwide, free-of-charge
patent license to make, have made, use, offer to sell, sell, import and
otherwise transfer the Package with respect to any patent claims
licensable by the Copyright Holder that are necessarily infringed by the
Package. If you institute patent litigation (including a cross-claim or
counterclaim) against any party alleging that the Package constitutes
direct or contributory patent infringement, then this Artistic License
to you shall terminate on the date that such litigation is filed.

lib/APP/REST/ParallelMyUA.pm  view on Meta::CPAN

Any use, modification, and distribution of the Standard or Modified
Versions is governed by this Artistic License. By using, modifying or
distributing the Package, you accept this license. Do not use, modify,
or distribute the Package, if you do not accept this license.

If your Modified Version has been derived from a Modified Version made
by someone other than you, you are nevertheless required to ensure that
your Modified Version complies with the requirements of this license.

This license does not grant you the right to use any trademark, service
mark, tradename, or logo of the Copyright Holder.

This license includes the non-exclusive, worldwide, free-of-charge
patent license to make, have made, use, offer to sell, sell, import and
otherwise transfer the Package with respect to any patent claims
licensable by the Copyright Holder that are necessarily infringed by the
Package. If you institute patent litigation (including a cross-claim or
counterclaim) against any party alleging that the Package constitutes
direct or contributory patent infringement, then this Artistic License
to you shall terminate on the date that such litigation is filed.

lib/APP/REST/RestTestSuite.pm  view on Meta::CPAN

use warnings FATAL => 'all';
use Data::Dumper;
use HTTP::Request;
use Time::HiRes qw( time sleep );
use File::Path;
use Cwd;
use LWP::UserAgent;
use APP::REST::ParallelMyUA;


use constant LOG_FILE     => 'rest_client.log';
use constant ERR_LOG_FILE => 'rest_client_error.log';
use constant LINE         => '=' x 50;

$|                    = 1;    #make the pipe hot
$Data::Dumper::Indent = 1;

=head1 NAME

APP::REST::RestTestSuite - Suite for testing restful web services 

=head1 VERSION

lib/APP/REST/RestTestSuite.pm  view on Meta::CPAN

my $suite = APP::REST::RestTestSuite->new();

$suite->execute_test_cases( $suite->get_test_cases() );
my ( $cases_in_config, $executed, $skipped, $passed, $failed ) =
  $suite->get_result_summary();

#OR

use APP::REST::RestTestSuite;

# overrides the default config and log file paths
my $suite = APP::REST::RestTestSuite->new(
    REST_CONFIG_FILE => <config file>,
    LOG_FILE_PATH    => <path>,
);

$suite->execute_test_cases( $suite->get_test_cases() );
my ( $cases_in_config, $executed, $skipped, $passed, $failed ) =
  $suite->get_result_summary();

 

lib/APP/REST/RestTestSuite.pm  view on Meta::CPAN

sub get_test_cases {
    my ( $self, %args ) = @_;

    if ( $self->{test_cases} ) {
        return %{ $self->{test_cases} };
    } else {
        return undef;
    }
}

=head2 get_log_file_handle


=cut

sub get_log_file_handle {
    my ( $self, %args ) = @_;

    return $self->{file}->{log_file_handle};
}

=head2 get_err_log_file_handle


=cut

sub get_err_log_file_handle {
    my ( $self, %args ) = @_;

    return $self->{file}->{err_log_file_handle};
}

=head2 get_config_file_handle


=cut

sub get_config_file_handle {
    my ( $self, %args ) = @_;

lib/APP/REST/RestTestSuite.pm  view on Meta::CPAN


=head2 get_result_summary


=cut

sub get_result_summary {
    my ( $self, %args ) = @_;

    return (
        $self->{test_result_log}->{test_cases_in_config},
        $self->{test_result_log}->{test_cases_exececuted},
        $self->{test_result_log}->{test_cases_skipped},
        $self->{test_result_log}->{test_cases_passed},
        $self->{test_result_log}->{test_cases_failed},
    );
}

=head2 validate_test_cases


=cut

sub validate_test_cases {
    my ($self) = shift;

lib/APP/REST/RestTestSuite.pm  view on Meta::CPAN



    my ( $config, $total, $total_response_time, $skip, $pass, $fail ) = (0) x 6;
    my ( $uri, $method, $req_content_type, $req_body, $status ) = (undef) x 5;
    my ( $request,  $response ) = (undef) x 2;
    my ( $username, $password ) = (undef) x 2;

    $username = $self->{username};
    $password = $self->{password};

    my $fh     = $self->get_log_file_handle();
    my $err_fh = $self->get_err_log_file_handle();

    if ( $self->{html_log_required}
        && ( $self->{html_log_required} =~ /yes/i ) )
    {
        print $fh
          qq|<HTML> <HEAD> <TITLE>LOG for $self->{endpoint}</TITLE> </HEAD>|
          . qq|<BODY><textarea rows="999999" cols="120" style="border:none;">|;
        print $err_fh
qq|<HTML> <HEAD> <TITLE>ERROR LOG for $self->{endpoint}</TITLE> </HEAD>|
          . qq|<BODY><textarea rows="999999" cols="120" style="border:none;">|;
    }

    print STDERR "\nTest Suite executed on $self->{endpoint}\n";

lib/APP/REST/RestTestSuite.pm  view on Meta::CPAN

        my $start_time = time;
        $response = $ua->request($request);
        $total++;
        my $exec_time = $self->delta_time( start_time => $start_time );
        $total_response_time += $exec_time;
        $exec_time = sprintf( "%.2f", $exec_time );

        print STDERR " [Completed in $exec_time ms]\n";
        print $fh " [Completed in $exec_time ms]\n";

        $self->_print_logs(
            fh       => $fh,
            uri      => $uri,
            method   => $method,
            req_body => $req_body,
        );
        $self->_print_logs(
            fh        => $fh,
            res       => $response,
            exec_time => $exec_time,
        );

        #Level-1 check => check for response status code
        #Level-2 check => check for expected response content_type
        my $resp_code = $response->code;
        if ( $status =~ m/$resp_code/ ) {
            my $failed = 0;

lib/APP/REST/RestTestSuite.pm  view on Meta::CPAN

                    print $err_fh
                      "Executing Test case $count => $tc->{test_case}";
                    print $err_fh
                      "\n*********ATTENTION CONTENT TYPE ERROR ******";
                    print $err_fh
"\n\nExpected content_type is $expected_response_content_type\n";
                    print $err_fh
"content_type recieved in response is $respose_content_type\n";
                    print $err_fh
                      "\n*********ATTENTION CONTENT TYPE ERROR ******";
                    $self->_print_logs(
                        fh       => $err_fh,
                        uri      => $uri,
                        method   => $method,
                        req_body => $req_body,
                    );
                    $self->_print_logs(
                        fh        => $err_fh,
                        res       => $response,
                        exec_time => $exec_time,
                    );
                }
            }
            ($failed) ? $fail++ : $pass++;
        } else {
            $fail++;
            print $err_fh "\n", LINE, "\n";
            print $err_fh "Executing Test case $count => $tc->{test_case}";
            $self->_print_logs(
                fh       => $err_fh,
                uri      => $uri,
                method   => $method,
                req_body => $req_body,
            );
            $self->_print_logs(
                fh        => $err_fh,
                res       => $response,
                exec_time => $exec_time,
            );
        }
    }

    #convert milli seconds to seconds for total_exec_time
    $total_response_time = sprintf( "%.2f", $total_response_time / 1000 );
    my $avg_response_time =
      sprintf( "%.2f", ( $total_response_time * 1000 ) / $total );

    print STDERR "\nComplete test case report is in $self->{file}->{log_file}";
    print STDERR
      "\nFailed test case report is in $self->{file}->{err_log_file}\n\n";

    print STDERR
"Response time of $total web service calls => [$total_response_time seconds]\n";
    print STDERR
"Average response time of a web service => [$avg_response_time milli seconds]\n\n";

    print $fh
"Response time of $total web service calls => [$total_response_time seconds]\n";
    print $fh
"Average response time of a web service => [$avg_response_time milli seconds]\n\n";

    if ( $self->{html_log_required}
        && ( $self->{html_log_required} =~ /yes/i ) )
    {
        print $fh qq|</textarea></BODY></HTML>|;
        print $err_fh qq|</textarea></BODY></HTML>|;
    }

    $self->{test_result_log} = {
        test_cases_in_config  => $config,
        test_cases_exececuted => $total,
        test_cases_skipped    => $skip,
        test_cases_passed     => $pass,
        test_cases_failed     => $fail,
    };

    close($fh);
    close($err_fh);

lib/APP/REST/RestTestSuite.pm  view on Meta::CPAN

    $pua->default_header('Accept' => '*/*'); # to get cross platform support

    my ( $config, $total, $total_response_time, $skip, $pass, $fail ) = (0) x 6;
    my ( $uri, $method, $req_content_type, $req_body, $status ) = (undef) x 5;
    my ( $request,  $response ) = (undef) x 2;
    my ( $username, $password ) = (undef) x 2;

    $username = $self->{username};
    $password = $self->{password};

    my $fh = $self->get_log_file_handle();

    if ( $self->{html_log_required}
        && ( $self->{html_log_required} =~ /yes/i ) )
    {
        print $fh
          qq|<HTML> <HEAD> <TITLE>LOG for $self->{endpoint}</TITLE> </HEAD>|
          . qq|<BODY><textarea rows="999999" cols="120" style="border:none;">|;
    }

    print STDERR "\nTest Suite executed on $self->{endpoint}\n";
    print $fh "\nTest Suite executed on $self->{endpoint}\n";

    my @reqs;

lib/APP/REST/RestTestSuite.pm  view on Meta::CPAN

        my $response  = $entries->{$_}->response;
        my $tick      = $entries->{$_}->{tick};
        my $exec_time = ( $tick->{end} - $tick->{start} ) * 1000 ;

        $total_response_time += $exec_time;
        $exec_time =  sprintf( "%.2f", $exec_time );

        print STDERR "\n", $response->request->url,
          "\n !  Response Status [", $response->code,
          "]\tResponse Time [$exec_time ms]";
        $self->_print_logs(
            fh       => $fh,
            uri      => $response->request->url,
            method   => $response->request->method,
            req_body => ''
        );
        $self->_print_logs(
            fh        => $fh,
            res       => $response,
            exec_time => $exec_time,
        );

    }

    #convert milli seconds to seconds for total_exec_time
    $total_response_time = sprintf( "%.2f", $total_response_time / 1000 );
    my $avg_response_time =
      sprintf( "%.2f", ( $total_response_time * 1000 ) / $total );

    print STDERR
      "\n\n\nComplete test case report is in $self->{file}->{log_file}";

    print STDERR
"\n\nResponse time of $total web service calls => [$total_response_time seconds]\n";
    print STDERR
"Average response time of a web service => [$avg_response_time milli seconds]\n\n";

    print $fh
"\n\nResponse time of $total web service calls => [$total_response_time seconds]\n";
    print $fh
"Average response time of a web service => [$avg_response_time milli seconds]\n\n";

    if ( $self->{html_log_required}
        && ( $self->{html_log_required} =~ /yes/i ) )
    {
        print $fh qq|</textarea></BODY></HTML>|;
    }

    $self->{test_result_log} = {
        test_cases_in_config  => $config,
        test_cases_exececuted => $total,
        test_cases_skipped    => $skip,
        test_cases_passed     => $pass,
        test_cases_failed     => $fail,
    };

    close($fh);

}

lib/APP/REST/RestTestSuite.pm  view on Meta::CPAN

    $self->_init_config_file_handle(%args);

    # Read the config file based on the type of the input file (xml or text)
    if ( $args{CONFIG_FILE_TYPE} && ( $args{CONFIG_FILE_TYPE} =~ /xml/i ) ) {

        #Implement the xml reading
    } else {
        $self->_init_read_config(%args);
    }

    $self->_init_log_file_handle(%args);

    $self->_init_rest_base_uri(%args);
}

sub _init_config_file_handle {
    my ( $self, %args ) = @_;

    $self->_init_config_files(%args);

    my $file = $self->{file};
    if ( $file->{config_file} ) {
        $file->{config_file_handle} =
          $self->_open_fh( FILE => $file->{config_file}, MODE => 'READ' );
    } else {
        $file->{config_file_handle} = \*APP::REST::RestTestSuite::DATA;
    }

    $self->{file} = $file;
}

sub _init_log_file_handle {
    my ( $self, %args ) = @_;

    $self->_init_log_files(%args)
      ;    #Make compatible with windows and linux logging

    my $file = $self->{file};

    $file->{log_file_handle} =
      $self->_open_fh( FILE => $file->{log_file}, MODE => 'WRITE' );
    $file->{err_log_file_handle} =
      $self->_open_fh( FILE => $file->{err_log_file}, MODE => 'WRITE' );

    $self->{file} = $file;
}

sub _init_read_config {
    my ( $self, %args ) = @_;

    my $fh = $self->get_config_file_handle();

    my @buffer           = ();

lib/APP/REST/RestTestSuite.pm  view on Meta::CPAN

        $separator = '/';
    }

    my $scfg = getcwd() || $ENV{PWD};
    my $scfg_file = $scfg . $separator . 'rest-project-xxxx.txt';

    $self->{file}->{sample_config_file} = $scfg_file;

}

sub _init_log_files {
    my ( $self, %args ) = @_;

    my $separator;
    if ( $^O =~ /Win/ ) {
        $separator = '\\';
    } else {
        $separator = '/';
    }

    my $log_path = $args{LOG_FILE_PATH} || getcwd() || $ENV{PWD};
    my $log_dir = $log_path . $separator . 'LOG';

    eval { mkpath( $log_dir, 0, 0755 ) unless ( -d $log_dir ); };

    if ($@) {
        my $err = $@;
        $err =~ s/line\s+\d+//g;
        die qq|Unable to create LOG directory ERROR: $err\n|;
    }

    my $log_file = join(
        $separator,
        (
            $log_dir,
            (
                $self->{html_log_required}
                  && ( $self->{html_log_required} =~ /yes/i )
              )
            ? LOG_FILE
              . ".html"
            : LOG_FILE
        )
    );
    my $error_log_file = join(
        $separator,
        (
            $log_dir,
            (
                $self->{html_log_required}
                  && ( $self->{html_log_required} =~ /yes/i )
              )
            ? ERR_LOG_FILE
              . ".html"
            : ERR_LOG_FILE
        )
    );
    $self->{file}->{log_file}     = $log_file;
    $self->{file}->{err_log_file} = $error_log_file;
}

sub _open_fh {
    my ( $self, %args ) = @_;

    my ( $fh, $err ) = (undef) x 2;

    my $file = $args{FILE};
    my $mode = $args{MODE};

lib/APP/REST/RestTestSuite.pm  view on Meta::CPAN


    return unless ( $_[0] );

    my $str = $_[0];
    $str =~ s/^\s+//g;
    $str =~ s/\s+$//g;

    return $str;
}

sub _print_logs {
    my ( $self, %args ) = @_;

    no warnings;

    my $fh       = $args{fh};
    my $res      = $args{res};
    my $uri      = $args{uri};
    my $method   = $args{method};
    my $req_body = $args{req_body};

lib/APP/REST/RestTestSuite.pm  view on Meta::CPAN

Any use, modification, and distribution of the Standard or Modified
Versions is governed by this Artistic License. By using, modifying or
distributing the Package, you accept this license. Do not use, modify,
or distribute the Package, if you do not accept this license.

If your Modified Version has been derived from a Modified Version made
by someone other than you, you are nevertheless required to ensure that
your Modified Version complies with the requirements of this license.

This license does not grant you the right to use any trademark, service
mark, tradename, or logo of the Copyright Holder.

This license includes the non-exclusive, worldwide, free-of-charge
patent license to make, have made, use, offer to sell, sell, import and
otherwise transfer the Package with respect to any patent claims
licensable by the Copyright Holder that are necessarily infringed by the
Package. If you institute patent litigation (including a cross-claim or
counterclaim) against any party alleging that the Package constitutes
direct or contributory patent infringement, then this Artistic License
to you shall terminate on the date that such litigation is filed.

lib/APP/REST/RestTestSuite.pm  view on Meta::CPAN

#   [END]
################
#Set below values to configure the base URL for all test cases

####################
#START_COMMON_CONFIG
################################################################################
  endpoint                  : www.thomas-bayer.com 
  port                      :
  base_uri                  : /sqlrest 
  html_log_required         : no 
  username                  : 

################################################################################
#END_COMMON_CONFIG
##################

#####################
#START_TEST_CASE
#####################
  test_case                : get_product

script/rest-client  view on Meta::CPAN

#!/usr/bin/env perl
use strict;
use warnings;
use File::Basename;
use Getopt::Long;
use POSIX;
use APP::REST::RestTestSuite;
use Data::Dumper;
$Data::Dumper::Indent = 1;

my ( $config_file, $log_dir, $action, $suite );
my $client  = File::Basename::basename($0);
my %options = (
    'c|configfile=s'      => \$config_file,
    'l|logdir=s'          => \$log_dir,
    'r|run-test-suite'    => \$action->{runtestsuite},
    't|test-load=s'       => \$action->{testload},
    's|get-sample-config' => \$action->{getsampleconfig},
    'd|debug'             => \$action->{debug},
    'h|help'              => \&usage,
    'V|version' =>
      sub { print "Version : ", APP::REST::RestTestSuite->VERSION, "\n"; exit; },

);

script/rest-client  view on Meta::CPAN


sub usage {
    print STDERR <<HELP;

Usage: $client [options] command [...]

Options:
  -h,--help                 Display this usage. 
  -V,--version              Print the version of the tool. 
  -c,--configfile=<file>    Input the config file with full path.
  -l,--logdir=<dir>         Input full path of the directory where you want to log the test results.
  -t,--test-load=n          Test the average response time by simulating 'n' number of requests on the web server.

Commands:
  -r,--run-test-suite       Test the configured web services defined in the config file.
  -g,--get-sample-config    Get a sample config file to configure your web services as test suite. 

***Note: 
By default tool uses the sample-config file. You need to get that and configure the suite.

Examples:

script/rest-client  view on Meta::CPAN

                # Get sample config file for configuring web services in the current directory.

  $client --run-test-suite --configfile=<rest_config_file> 
                # Execute the test suite against the supplied config file. 
                # Supply the full path of config file if it is not present in current directory.

  $client --test-load=10 --configfile=<rest_config_file> 
                # Send parallel requests (10* number of web services configured in config file). 
                # Give average response time by simulating huge traffic in the web server.

  $client --run-test-suite --configfile=<rest_config_file>  --logdir=<log-directory-path>
  $client --test-load=10   --configfile=<rest_config_file>  --logdir=<log-directory-path>
                # Create LOG files in the path specified by executing the test cases. 

HELP
    exit;
}

print
"\n===============================Rest Test Automation Tool=============================\n";

if ( $^O =~ /Win/ ) {
    $config_file =~ s/\//\\/g if ($config_file);
    $log_dir     =~ s/\//\\/g if ($log_dir);
}
if ( $config_file && $log_dir ) {

    print "Parsing Config File : $config_file\n";
    print "Using log dir as    : $log_dir\n";

    $suite = new APP::REST::RestTestSuite(
        REST_CONFIG_FILE => $config_file,
        LOG_FILE_PATH    => $log_dir,
    );
} elsif ($config_file) {

    print "Parsing Config File : $config_file\n\n";
    $suite = new APP::REST::RestTestSuite( REST_CONFIG_FILE => $config_file, );

} elsif ($log_dir) {

    print <<HELP;
  Using log dir as    : $log_dir

  Using the default test suite. This is just for a demo purpose.
  Use below options to specify the config file and log path.

  $client --configfile=<rest_config_file> --logdir=<log-directory-path>

HELP
    $suite = new APP::REST::RestTestSuite( LOG_FILE_PATH => $log_dir, );

} else {
    unless ( $action->{getsampleconfig} ) {
        print <<HELP;
  Using the default test suite. This is just for a demo purpose.
  Use below options to specify the config file and log path.

  $client --configfile=<rest_config_file> --logdir=<log-directory-path>

  Use below option to get a sample config. Edit the config file to configure your web services

  $client --get-sample-config

HELP
    }
    $suite = new APP::REST::RestTestSuite();
}

script/rest-client  view on Meta::CPAN

rest-client - Test automation tool for restful web services

=head1 SYNOPSIS

Usage: rest-client [options] command [...]

Options:
  -h,--help                 Display this usage. 
  -V,--version              Print the version of the tool. 
  -c,--configfile=<file>    Input the config file with full path.
  -l,--logdir=<dir>         Input full path of the directory where you want to log the test results.
  -t,--test-load=n          Test the average response time by simulating 'n' number of requests on the web server.

Commands:
  -r,--run-test-suite       Test the configured web services defined in the config file.
  -g,--get-sample-config    Get a sample config file to configure your web services as test suite. 

***Note: 
By default tool uses the sample-config file. You need to get that and configure the suite.

Examples:

script/rest-client  view on Meta::CPAN

                # Get sample config file for configuring web services in the current directory.

  rest-client --run-test-suite --configfile=<rest_config_file> 
                # Execute the test suite against the supplied config file. 
                # Supply the full path of config file if it is not present in current directory.

  rest-client --test-load=10 --configfile=<rest_config_file> 
                # Send parallel requests (10* number of web services configured in config file). 
                # Give average response time by simulating huge traffic in the web server.

  rest-client --run-test-suite --configfile=<rest_config_file>  --logdir=<log-directory-path>
  rest-client --test-load=10   --configfile=<rest_config_file>  --logdir=<log-directory-path>
                # Create LOG files in the path specified by executing the test cases. 


=head1 SEE ALSO
 
L<https://github.com/rkmithun/APP-REST-RestTestSuite>
 
=cut



( run in 1.091 second using v1.01-cache-2.11-cpan-49f99fa48dc )