Thursday, March 16, 2006

Testing if a Perl script compiles - compile_ok

A co-worker and I were pair programming a test suite the other day, and needed to test if a Perl script compiles - not a library or module but an executeable script, so the typical:
    require_ok()
use_ok()
functions provided by Test::More don't do exactly what we wanted.

The short story is that we ended up doing something like this:
  eval {
$output = `perl -c $script 2>&1`;
chomp $output;
};
is($output, "$script syntax OK", "$script compiles");
We later looked for a more general, better solution, and a colleague posted on the perl-qa mailing list, but the bottom line is that a more elegant solution still involves executing a new perl interpreter, but in a platform-independent way (perhaps using IPC::Open3 or something.) It's also likely that a better test is to ignore the output altogether and just check the return code from the compile process (the call to perl -c.)

March 18, 2006 update: Jeff Thalhammer found that a colleague Pierre Denis provides a syntax_ok method in Test::Strict that does what we want.
More update - I was prodded by Randall Schwartz to post why you should be careful when "only" compiling Perl code - see BEGIN Blocks Considered Harmful.
Tags: ,

4 comments:

Randal L. Schwartz said...

Beware that "perl -c" still executes "BEGIN" blocks (and by extension, anything in the body of anything pulled in with "use"), so it's not safe to use with untrusted code.

For example:

perl -c -e 'BEGIN { print "running!\n" }'

will print "running!".

Matisse Enzer said...

You are quite correct!
In fact, I have sent email to a couple of vendors of Perl IDE's and posted in the Eclipse/EPIC forum about this "BEGIN Blocks Considered Harmful" situation (See http://tinyurl.com/oja4v)
Hmmm. Maybe time for a proper blog post about it.

eliben said...

Hi Matisse,

A small (and off topic) question to you - how do you post source code nicely in your Blogger posts, using Blogger's post editor ?

Matisse Enzer said...

Hi eliben - the answer is that I use the "Edit HTML" feature of the editor, and enclose the code in <pre> </pre>