1. ホーム
  2. perl

[解決済み] Perlのビルド、ユニットテスト、コードカバレッジ。完全な実用例

2023-06-02 14:23:35

質問

Perl のビルド プロセス、ユニット テスト、およびコード カバレッジに関して私が見つけたほとんどの Stackoverflow の回答は、単に CPAN にあるドキュメントを指しています。 それは完全なドキュメントが存在することになっている場所であるため、CPAN モジュールを指すことに全く問題はありません。 しかし、多くの場合、完全な動作するコード例を見つけるのに苦労しました。

典型的なチュートリアルの "Hello World" のサンプルソースコードのような、しかし、ユニットテストとコードカバレッジ分析で構築プロセスを実証するサンプルのように、ダウンロードまたは IDE に貼り付けることができる実際の作業コードサンプルをインターネット上で検索してきました。 どなたか、これらの技術とプロセスを実証する完全な作業プロジェクトの小さな例をお持ちではないでしょうか?

(私は小さな動作例を持っており、それで私自身の質問に答えますが、おそらく私が考え出したものよりも良い例を持っている他の SO ユーザーがいるでしょう)。

どのように解決するのですか?

時間がかかり、また、多くの異なるソースから小さなスニペットを取り、それらを一緒に溶かす必要がありましたが、ユニットテストとコードカバレッジ分析 & レポートを含む Perl ビルドプロセスを Perl 初心者に十分に示す小さな作業例ができたと思います。 (私が使っている アクティブステート アクティブパール v5.10.0 を Windows XP Pro PC 上で使用しています。 モジュール::ビルド , テスト::詳細 , デベロッパー::カバー )

まず、Perlプロジェクトのディレクトリを作成し、その下に"lib"ディレクトリと"t"ディレクトリを作成します。

HelloPerlBuildWorld
        |
        |----------> lib
        |
        |----------> t

"lib" ディレクトリに "HelloPerlBuildWorld.pm" という名前のテキスト ファイルを作成します。 このファイルは、あなたがビルドしてテストするPerlモジュールです。 このファイルに、以下の内容を貼り付けてください。

use strict;
use warnings;
package HelloPerlBuildWorld;

$HelloPerlBuildWorld::VERSION = '0.1';

sub hello {
   return "Hello, Perl Build World!";
}

sub bye {
   return "Goodbye, cruel world!";
}

sub repeat {
   return 1;
}

sub argumentTest {
    my ($booleanArg) = @_;

    if (!defined($booleanArg)) {
        return "null";
    }
    elsif ($booleanArg eq "false") {
        return "false";
    }
    elsif ($booleanArg eq "true") {
        return "true";
    }
    else {
        return "unknown";
    }

   return "Unreachable code: cannot be covered";
}

1;

t"ディレクトリに、"HelloPerlBuildWorld.t" という名前のテキストファイルを作成します。 このファイルは、上記の Perl モジュールを完全にテストするためのユニット テスト スクリプトです。 このファイルに、以下の内容を貼り付けてください。

use strict;
use warnings;
use Test::More qw(no_plan);

# Verify module can be included via "use" pragma
BEGIN { use_ok('HelloPerlBuildWorld') };

# Verify module can be included via "require" pragma
require_ok( 'HelloPerlBuildWorld' );

# Test hello() routine using a regular expression
my $helloCall = HelloPerlBuildWorld::hello();
like($helloCall, qr/Hello, .*World/, "hello() RE test");

# Test hello_message() routine using a got/expected routine
is($helloCall, "Hello, Perl Build World!", "hello() IS test");

# Do not test bye() routine

# Test repeat() routine using a got/expected routine
for (my $ctr=1; $ctr<=10; $ctr++) {
    my $repeatCall = HelloPerlBuildWorld::repeat();
    is($repeatCall, 1, "repeat() IS test");
}

# Test argumentTest() 
my $argumentTestCall1 = HelloPerlBuildWorld::argumentTest();
is($argumentTestCall1, "null", "argumentTest() IS null test");

# Test argumentTest("true") 
my $argumentTestCall2 = HelloPerlBuildWorld::argumentTest("true");
is($argumentTestCall2, "true", "argumentTest() IS true test");

# Test argumentTest("false") 
my $argumentTestCall3 = HelloPerlBuildWorld::argumentTest("false");
is($argumentTestCall3, "false", "argumentTest() IS false test");

# Test argumentTest(123) 
my $argumentTestCall4 = HelloPerlBuildWorld::argumentTest(123);
is($argumentTestCall4, "unknown", "argumentTest() IS unknown test");

さて、トップレベルのプロジェクトディレクトリに戻り、"Build.PL" という名前のテキストファイルを作成します。 このファイルは、後で使用するビルドスクリプトを作成するためのものです。 このファイルに、以下の内容を貼り付けてください。

use strict;
use warnings;
use Module::Build;

my $builder = Module::Build->new(
    module_name         => 'HelloPerlBuildWorld',
    license             => 'perl',
    dist_abstract       => 'HelloPerlBuildWorld short description',
    dist_author         => 'Author Name <[email protected]>',
    build_requires => {
        'Test::More' => '0.10',
    },
);

$builder->create_build_script();

これで、必要なファイルはすべて揃いました。 では、プロジェクトのトップレベルのディレクトリのコマンドラインから、次のコマンドを入力してください。

perl Build.PL

のようなものが表示されます。

Checking prerequisites...
Looks good

Creating new 'Build' script for 'HelloPerlBuildWorld' version '0.1'

これで、以下のコマンドでユニットテストを実行できるはずです。

Build test

そして、これに似たものを見てください。

Copying lib\HelloPerlBuildWorld.pm -> blib\lib\HelloPerlBuildWorld.pm
t\HelloPerlBuildWorld....ok
All tests successful.
Files=1, Tests=18,  0 wallclock secs ( 0.00 cusr +  0.00 csys =  0.00 CPU)

コードカバレッジ解析で単体テストを実行するには、次のようにしてみてください。

Build testcover

と、このような順番で表示されます。

t\HelloPerlBuildWorld....ok
All tests successful.
Files=1, Tests=18, 12 wallclock secs ( 0.00 cusr +  0.00 csys =  0.00 CPU)
cover
Reading database from D:/Documents and Settings/LeuchKW/workspace/HelloPerlBuildWorld/cover_db


----------------------------------- ------ ------ ------ ------ ------ ------
File                                  stmt   bran   cond    sub   time  total
----------------------------------- ------ ------ ------ ------ ------ ------
D:/Perl/lib/ActivePerl/Config.pm       0.0    0.0    0.0    0.0    n/a    0.0
D:/Perl/lib/ActiveState/Path.pm        0.0    0.0    0.0    0.0    n/a    0.0
D:/Perl/lib/AutoLoader.pm              0.0    0.0    0.0    0.0    n/a    0.0
D:/Perl/lib/B.pm                      18.6   16.7   13.3   19.2   96.4   17.6
 ...
[SNIP]
 ...
D:/Perl/lib/re.pm                      0.0    0.0    0.0    0.0    n/a    0.0
D:/Perl/lib/strict.pm                 84.6   50.0   50.0  100.0    0.0   73.1
D:/Perl/lib/vars.pm                   44.4   36.4    0.0  100.0    0.0   36.2
D:/Perl/lib/warnings.pm               15.3   12.1    0.0   11.1    0.0   12.0
D:/Perl/lib/warnings/register.pm       0.0    0.0    n/a    0.0    n/a    0.0
blib/lib/HelloPerlBuildWorld.pm       87.5  100.0    n/a   83.3    0.0   89.3
Total                                  9.9    4.6    2.8   11.3  100.0    7.6
----------------------------------- ------ ------ ------ ------ ------ ------


Writing HTML output to D:/Documents and Settings/LeuchKW/workspace/HelloPerlBuildWorld/cover_db/coverage.html ...
done.

(誰か、Perl以外のすべてのライブラリを無視して、私が書いた1つのファイルだけを報告してくれるようにCoverを設定する方法を教えてください。 CPANのドキュメントによると、Cover filteringを動作させることができなかったのです!)

ここで、トップレベルのディレクトリを更新すると、"cover_db" という新しいサブディレクトリが表示されます。 そのディレクトリに移動し、"coverage.html" ファイルをダブルクリックして、お気に入りの Web ブラウザーでコード カバレッジ レポートを開いてください。 このレポートでは、ファイル名をクリックすると、Perl モジュールの詳細なステートメント、ブランチ、条件、サブルーチンのカバレッジ統計が、実際のソースコードの横に表示されます。 このレポートでは、"bye()" ルーチンを全くカバーしていないこと、また、予想通りカバーされていない到達不能なコード行があることがわかります。



(ソース leucht.com )

IDE でこのプロセスを自動化するためにできることのもう 1 つは、上で手動で行ったビルド ターゲットのいくつかをコマンド ラインから明示的に実行する "Build.PL" タイプのファイルをさらにいくつか作成することです。 例えば、私は以下のような内容の"BuildTest.PL"ファイルを使用しています。

use strict;
use warnings;
use Module::Build;

my $build = Module::Build->resume (
  properties => {
    config_dir => '_build',
  },
);

$build->dispatch('build');
$build->dispatch('test');

そして、このファイル ("perl BuiltTest.PL") をマウスで1回クリックするだけで実行できるように IDE をセットアップすると、コマンドラインから手動で実行する代わりに IDE からユニットテストのコードが自動的に実行されるようになります。 dispatch('test')" を "dispatch('testcover')" に置き換えると、コードカバレッジを自動実行することができます。 Module::Build から利用可能なビルドターゲットの完全なリストは "Build help" と入力してください。