Perlビルド、単体テスト、コードカバレッジ:完全な実例


86

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

典型的なチュートリアル「HelloWorld」のサンプルソースコードのように、ダウンロードまたはIDEに貼り付けることができる実際の動作コードサンプルをインターネット全体で検索してきましたが、単体テストとコードを使用したビルドプロセスを示す例です。カバレッジ分析。これらのテクノロジーとプロセスを実証する完全な作業プロジェクトの小さな例を誰かが持っていますか?

(私には小さな実用的な例があり、それを使って自分の質問に答えますが、私が思いついたものよりも良い例を持っている他のSOユーザーがおそらくいるでしょう。)

回答:


105

しばらく時間がかかり、さまざまなソースから小さなスニペットを取り出してそれらを溶かすのにも時間がかかりましたが、ユニットテストやコードカバレッジを含むPerlビルドプロセスをPerl初心者に十分に示す小さな実用的な例があると思います分析とレポート。(私はWindows XP ProPCでActiveStateActivePerl v5.10.0を使用しています、Module :: BuildTest :: MoreDevel :: Cover

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_addy@goes.here>',
    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ライブラリを無視するようにCoverを構成する方法を教えてください。CPANドキュメントに従ってCoverフィルタリングを機能させることができませんでした!)

これで、最上位ディレクトリを更新すると、「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');

次に、マウスを1回クリックするだけでこのファイルを(「perlBuiltTest.PL」を介して)実行するようにIDEを設定すると、コマンドラインから手動で実行するのではなく、IDEから単体テストコードが自動的に実行されます。自動コードカバレッジ実行のために、「dispatch( 'test')」を「dispatch( 'testcover')」に置き換えます。Module :: Buildから利用できるビルドターゲットの完全なリストについては、「ビルドヘルプ」と入力してください。


1
BuiltTest.PLを設定するというあなたの考えは、私にはよく聞こえません。なぜ、あなただけ行うスクリプトを書くことができないBuild build当時とBuild test
Leon Timmermans

2
レオン、コマンドライン呼び出しを行うperlスクリプトを提案していますか?もしそうなら、サンプルのBuiltTest.PLファイルのようにプログラムで呼び出しを行うオブジェクト指向の方法がある場合は、コマンドライン呼び出しを行いたくありません。
Kurt W. Leucht 2009

1
それは必要ありません、私自身の答えを見てください
Leon Timmermans

2
Module :: BuildはCPAN用ではありません。CPANにない場合でも、さまざまなCPANツールからすべての機能を取得できます。プライベートモジュールであっても、同じプロセスでビルド、テスト、配布、およびインストールできます。
brian d foy 2009

4
Devel :: Coverで結果をフィルタリングするには、にオプションを追加します$ENV{HARNESS_PERL_SWITCHES}。例:-MDevel::Cover=+ignore,.t$,+inc,/app/lib,-select,MyModule.pmここ/app/libで、はアプリケーションプライベートライブラリであり、MyModule.pmはテスト中のモジュールです。
マイケルカーマン

14

Kurtに応えて、私は彼のBuiltTest.PLスクリプトに代わるこの代替案を提案します。

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

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

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

Build.PLによって構築されたデータベースを再利用します(したがって、すでに実行されていると想定します)。


完璧!ありがとう、レオン。私は自分の例に何か問題があることを知っていましたが、私はまだこのperlビルドのものに慣れていません!:-)
Kurt W. Leucht 2009


12

幻想役立つはmodule-starterモジュールのインストール、ドキュメントの作成とに住んでモジュールファイルのための良好なレイアウトを扱う使いやすいスケルトンプロジェクトを生成し、そして-私は考えます-コードカバレッジのサポートを。これは、Perlモジュール関連の取り組みにとってIMOの素晴らしいスタートです。

また、次のようなCPAN関連のツールを使用Module::Buildすることは、公開される可能性が低いモジュールであっても、非常に良い考えです。


7

(開示:私は著者です)

上記のようにすべてを並べ替えたら、次のステップに進み、Devel :: CoverX :: Coveredを次のように使用できます。

  • ソースファイルを指定して、そのソースファイルをカバーするテストファイルを一覧表示します。これは、ファイル、サブルーチン、および行レベルで実行できます。
  • テストファイルを指定して、そのテストファイルの対象となるソースファイルとサブファイルを一覧表示します。
  • ソースファイルを指定して、行ごと、またはサブごとのカバレッジの詳細について効率的にレポートします。

具体的なコマンドラインの例については、概要を参照してください。

Devel :: PerlySenseソースコードバッファ(INカバレッジ情報を表示するEmacsのサポートがありますスクリーンショット)、およびテストファイルをカバーから/に移動します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.