2009-06-23 10 views
3

いくつかのPerlスクリプトの回帰システム(ではなく、ユニットテスト)を構築しています。テストスイートからPerlプログラムをコンパイルする方法をテストできますか?

システムのコアコンポーネントは

`perl script.pl @params 1>stdoutfile 2>stderrfile`; 

しかし、実際にスクリプトに取り組んでの過程で、彼らは時々(ショック!)をコンパイルしないでくださいされています。しかしperl自体が正しく実行されます。しかし、私は、Perlがコンパイルに失敗した(したがってstderrに書き込んだ)のか、スクリプトが入力にバーコード化された(したがってstderrに書き込んだ)のかどうかをstderrで検出する方法を知らない。

Perlエラーメッセージを徹底的に見つけずに、stderrファイルをグリッピングすることなく、プログラムが実行されたかどうかを検出するにはどうすればよいですか?

答えて

6

それは二段階でこれを実行するのが最も簡単かもしれません:

system('$^X -c script.pl'); 
if ($? == 0) { 
    # it compiled, now let's see if it runs 
    system('$^X script.pl', @params, '1>stdoutfile', '2>stderrfile'); 
    # check $? 
} 
else { 
    warn "script.pl didn't compile"; 
} 

ではなくperl$^Xの使用に注意してください。これはより柔軟で堅牢です。これは、あなたのパスに最初に表示されるインタープリタの代わりに、同じインストールから実行していることを保証します。システムコールはあなたの環境(PERL5LIBを含む)を継承するので、異なるバージョンのperlを生成すると、互換性のエラーを診断するのが難しくなる可能性があります。

+3

あなたは常に$^Xを使うべきです。私はそれを使用したたびに、ハードコードされた 'perl'に噛まれてしまいました。問題は、子プロセスがPERL5LIBを継承していることです。これは、PATHの最初のperlで間違っている可能性があります。あなたは奇妙なライブラリの不一致のエラーで終わるでしょう。 –

+0

Heh。それは醜いです。それは必ずしも問題ではありませんが(WindowsユーザーはPerlの複数のバージョンをインストールすることはほとんどありません)、$^Xを使用することは決して有害ではありません。私はそれに応じて答えを更新します。 –

+0

@Michael Carman Ah-em ...私はCygwin、Strawberry、ActiveState Perlだけでなく、VC Expressを使って最初からコンパイルしたものもあります。 –

2

変数$?を見てください。ステータスが最後のパイプ 近い、バッククォート( "` `")コマンド、待つ 成功したコール()または waitpidの()によって、またはシステムから返さ

(:perldoc perlvarから

) オペレータ。これは、 という従来のUnixのwait()システムコール によって返されたステータスワードです( )。 したがって、サブプロセス の終了値は、実際に( "$?>> 8")、および "$?& 127は" が与える信号、もしあれば、 プロセスが死亡した、と "$?& 128" であります は、コアダンプが存在するかどうかを報告します。

+0

しかし、$はですか? * perl *か*スクリプト*の結果を返しますか?そしてPerlの戻り値は何ですか?私はグーグルで見つけられませんでした。 –

+0

いずれかである可能性があります。スクリプトがコンパイルされていることを確認するには、代わりに 'perl -c script.pl'を実行し、$?をテストしてください。 == 0. –

3

私はプログラムがコンパイルされることを確認したい場合は、私はそれがコンパイルされることを確認してください:)

ここで私は私のテストスイートの残りの部分を使用して実行するようにトン/ compile.tに入れるものです。スクリプトがコンパイルされない場合は、「ベイルアウト」のテストをすべて停止します。

 
use Test::More tests => 1; 

my $file = '...'; 

print "bail out! Script file is missing!" unless -e $file; 

my $output = `$^X -c $file 2>&1`; 

print "bail out! Script file does not compile!" 
    unless like($output, qr/syntax OK$/, 'script compiles'); 
+1

Test :: MoreにはBAIL_OUT()関数があります。 – Schwern

3

スクリプトは非常にテストするのが非常に難しいです。あなたはそれらを実行して、その出力をスクラップしなければなりません。彼らのユニットをテストすることはできません...またはできますか?

#!/usr/bin/perl -w 

# Only run if we're the file being executed by Perl 
main() if $0 eq __FILE__; 

sub main { 
    ...your code here... 
} 

1; 

他のライブラリと同様にスクリプトを読み込むことができます。

#!/usr/bin/perl -w 

use Test::More; 

require_ok("./script.pl"); 

main()を実行してテストすることもできます。 Test::Outputは、出力をキャプチャするのに便利です。引数を制御するにはlocal @ARGVと言うことができます。また、引数として@ARGVを取るようにmain()を変更することもできます(推奨)。

次に、main()を簡単に単体テストできる小さなルーチンに分割することができます。

+0

問題は、私はスクリプトを編集したくないということです。これはブラックボックスのテストアプローチであり、ユニットテストのアプローチではありません(独自の時間と場所があります)。 –

+0

あなたはブラックボックスだけではありません。コマンドラインでプログラムをテストすることで、高レベルの受入れテストが行​​われます。高レベルの受け入れテスト。これらのテストは、たくさんの中間コードを通してすべてをテストしなければならないので、書くのは難しいです。そして何かがうまくいかないときは、9381もののどれかになります。あなたは、コーディング中にテストの利点の多くを失う。そしてあなたはすでにあなたがスクリプトに取り組んでいると言っています。そうではなく、それは石で設定されています。最後に、私はあなたに他の人の答えの変種ではなく、別のアプローチを提供したかったのです。 – Schwern

関連する問題