Monks,

In considering how to automate testing on our (increasingly huge) application here at $work, I've been toying with creating a "script runner" in Perl, which would allow me (or my staff) to write scripts using Perl and some functions specific to driving our application, but without using (as much) object notation to manipulate the application. I haven't gotten any farther than a proof-of-concept, but I hope to pick your collective brains before I fall too far down the rabbit hole.

Here's a module which I'm using to test my "script runner" idea. If I were to move ahead, this would be significantly more involved, but I think it will help you get the idea what I'm talking about:

#! /usr/local/bin/perl package Product::Driver; use strict; use warnings; use Moose; has counter => ( isa => 'Int', default => 0, reader => 'value' ); sub add_one { my ( $self ) = @_; return ++$self->{'counter'}; } sub subtract_one { my ( $self ) = @_; return --$self->{'counter'}; } sub add_number { my ( $self, $amount ) = @_; return $self->{'counter'} += $amount; } sub subtract_number { my ( $self, $amount ) = @_; return $self->{'counter'} -= $amount; } sub reset_counter { my ( $self ) = @_; return $self->{'counter'} = 0; } 1;

Here's the "script runner" module that would read scripts and execute them

#! /usr/local/bin/perl package ScriptRunner; use strict; use warnings; use Product::Driver; use MooseX::Singleton; has driver => ( isa => 'Product::Driver' ); #Not yet implemented #has recorder => ( does => 'Tester::Recorder', required => 1 ); sub BUILD { my ( $self ) = @_; $self->_init_driver(); } sub _init_driver { my $self = ref($_[0]) ? shift : ScriptRunner->new(); $self->{'driver'} = Product::Driver->new(); } sub close_driver { my $self = ref($_[0]) ? shift : ScriptRunner->new(); $self->{'driver'} = undef; } sub start_driver { my $self = ref($_[0]) ? shift : ScriptRunner->new(); if ( $self->{'driver'} == undef ) { $self->_init_driver(); } } sub restart_driver { my $self = ref($_[0]) ? shift : ScriptRunner->new(); $self->close_driver(); $self->start_driver(); } sub check_success { my ( $self ) = ScriptRunner->new(); my $val = ( $_[0] ne '' ) ? $_[0] : 0; my $msg = $_[1] ? $_[1] : "Unknown Event"; # Eventually, instead of printing the result, there would be a # recorder module that would be available to record the test # results in some convenient, meaningful way. But for now... printf "%-20s%s\n", $val ? "PASSED TEST" : "FAILED TEST", $msg; } sub add_one { my ( $self ) = ScriptRunner->new(); return $self->{'driver'}->add_one; } sub add_number { my ( $self ) = ScriptRunner->new(); my ( $amount ) = @_; return $self->{'driver'}->add_number($amount); } sub subtract_one { my ( $self ) = ScriptRunner->new(); return $self->{'driver'}->subtract_one; } sub subtract_number { my ( $self ) = ScriptRunner->new(); my ( $amount ) = @_; return $self->{'driver'}->subtract_number($amount); } sub value { my ( $self ) = ScriptRunner->new(); return $self->{'driver'}->value; } sub reset_counter { my ( $self ) = ScriptRunner->new(); return $self->{'driver'}->reset_counter; } sub do_script { my $self = ref($_[0]) ? shift : ScriptRunner->new(); my ( $file ) = @_; if ( ! -f $file ) { die "$file not found!" } my $res = do $file; if ( $@ ) { die "Can't do $file\n", $@ } return $res; } 1;

A simple app that creates a ScriptRunner object and then feeds the filenames of scripts to be executed (specified on the command line).

#! /usr/local/bin/perl use strict; use warnings; use lib "./lib"; use ScriptRunner; my $runner = ScriptRunner->new(); # Do any necessary environmental setup here. Since this is # just a demo, there's nothing really to do. foreach my $f ( @ARGV ) { print "Running script file: $f\n"; $runner->do_script($f) }

And a sample script:

my $string = ''; $string .= add_one(); $string .= " "; $string .= add_number(50); $string .= " "; $string .= subtract_one(); $string .= " "; $string .= subtract_number(45); $string .= " "; $string .= value(); check_success ( $string eq "1 51 50 5 5", "This is a comment" ); return ( $string );

The code probably isn't the best at this point, I've only been trying to decide if I'm moving forward with this.

So, with all that in mind, here are my questions:

  1. Am I insane for trying to do this? Does this seem a reasonable thing to do, or should I just take a step back, remove the ScriptRunner idea, and buy a copy of Learning Perl for the testing staff?
  2. If this isn't a completely insane thing to do, does my approach seem reasonable? To be honest, it seems kind of unwieldy to add a function to the ScriptRunner for every function I add to the Product::Driver (there could end up being quite a lot of functions), but I'm not sure how else to proceed. Is there a better way to accomplish what I'm trying to do?

Thanks for your time and feedback.

Regards,

Bald Man Tom


In reply to On the merits of implementing a script running application by BaldManTom

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.