24

小さな Perl スクリプトを作成しましたが、そのテスト スイートを作成したいと考えています。useスクリプトをモジュールとして作成し、スクリプトで定義されたサブルーチンをインポートして、これらをテストできるとよいと思いました。スクリプトをスタンドアロンの Perl スクリプトと Perl モジュールの両方にする方法はありますか? (スクリプトを単一のファイルとして配布する予定なので、スクリプトを別のモジュールと「実行可能ファイル」に分割したくありません。)

または、スクリプトをテストするより良い方法はありますか?

4

7 に答える 7

33

ブライアンは今眠っているように見えるので、ここに彼がモジュリノスと呼んでいるものへのポインタがあります。これは基本的に、モジュールのように機能するスクリプトまたはスクリプトのように実行できるモジュールを作成するためのレシピです。あなたが探しているものとまったく同じように聞こえます。

Perlをマスターすることは間違いなく読む(そして買う)価値のある本です。

于 2009-01-22T12:32:16.807 に答える
8

(スクリプトを単一のファイルとして配布する予定なので、スクリプトを別のモジュールと「実行可能ファイル」に分割したくありません。)

ほとんどの人は、ビルド時にこのようにファイルをつなぎ合わせます。App :: Ack on the CPANは、このように構築できるものの例です。

アプリケーションを本当に適切にテストしたい場合は、機能をモジュールに入れてから、モジュールが提供する機能を実行するTest::Moreベースのテストスクリプトを作成する必要があります。その場合、実際のスクリプトはモジュールの薄いラッパーであり、通常は次のようになります。

#!/usr/bin/env perl
use Your::Class;
Your::Class->new(args => \@ARGV)->run;

参照:MooseX::Getopt

于 2009-01-22T12:09:10.893 に答える
4

私も同じことをしたいです。次のことをしない理由はありますか?(私は perl の専門家ではありませんが、解決策はうまくいくようです。):

スクリプトの冒頭で、スイッチ(「-test」)などを要求し、次のようなサブに分岐します。

my $myargs = CmdLineOptions->new( args=>\@ARGV );
if ($myargs->was_given(option=>"-test"))    { &tests; }

sub tests   {
    require "Test/More.pm";
    Test::More->import('no_plan');

    is(1,1,"my tests go here");
    exit;
}

(require と import を使用することで、テストを行わずに 'use Test::More' を使用したときに表示される '# No tests run!' メッセージを抑制します。オーバーヘッドも削減されると思います。)

于 2011-01-14T11:21:06.353 に答える
2

スクリプト自体をテストするか、スクリプトを構成するサブをテストするかによって異なります。スクリプトをテストする場合は、シェルスクリプトなどの外部テストの方が適切です。スクリプトを構成する関数をテストする場合は、それらのテストをスクリプト内のより多くの関数として記述するか、要素をPerlモジュールにリファクタリングして、モジュールをテストすることができます(これは実行したくないと言います)。 。

スクリプトが十分に小さい場合は、リファクタリングは必要ない場合があります。'-test'コマンドライン引数を追加し、test subを呼び出すだけで、他のすべてがテストされます。これを行う場合、私はある種の進行状況インジケーターを印刷するのが好きです(たとえば、合格するすべてのテストに対して「。」)。

ただし、スクリプトがより複雑な場合は、ビットを1つ以上のモジュールにリファクタリングし、Test::SimpleまたはTest::Moreを使用してテストすることを検討してください。

于 2009-01-22T12:14:18.137 に答える
1

Perl スクリプトを他のシェル コマンドと同じように呼び出して、シェル スクリプトでテスト スイートを作成してみませんか?

于 2009-01-22T11:25:07.643 に答える
0

一部の CGI スタイルの perl スクリプトをリモートでテストできるようにしている間 (CGI テスト モジュールをループせずに)、最終的に次のようなことを行いました。

ビン/myscript.pl:

use …;

do {
  return 1 if $ENV{INCLUDED_AS_MODULE};

  … original script without the subs …
};

sub some_sub {
 …
}
sub …
sub …

t/mytest.t:

use Test::More;
use FindBin qw/$Bin/;

BEGIN {
  $ENV{INCLUDED_AS_MODULE} = 1;
  my $filename = "$Bin/../bin/myscript.pl";
  do $filename or die "Unable to open '$filename': $! ($@)";
}

ok some_sub(), 'some sub returns true';
…
done_testing;

これにより、サブがテストのメイン名前空間にインポートされ、簡単にテストできます。

編集:そして、私が探していたものをさらに検索した後、modulinos基本的に私が行ったことに気付きましたが、ENV を介した通信を避け、すべてのコードをメソッドに入れ、caller() があるかどうかを確認するだけです:

https://www.perlmonks.org/bare/?node_id=537377 (以前の回答のリンクは機能していないようでした)

于 2020-11-10T02:06:48.900 に答える
0

1 つのサブをテストしたかったので、そのサブを perl ワンライナーでモジュールに抽出するハックなソリューションを使用しました。これは理解しやすく、モジュールをインストールする必要はありません (サブで段落を抽出します)もちろん壊れやすい名前)。したがって、私の Makefile には次のものがあります。

MyModule.pm: my_script.pl
    perl -00 -lnE 'if(/^\s*sub my_sub \{/){say "package MyModule;";say;say "1;";}' my_script.pl >|MyModule.pm
于 2019-04-10T07:57:50.780 に答える