ziguzagu.org

はじめてのTest::More

Chapter1の後半戦は、Test::More。

Perl Testing: A Developer's Notebook (Developers Notebook)

Test::MoreはTest::Simpleのスーパーセットで完全に置き換えて使ってOK、モジュールをただしく読み込めたかどうかなどのテスト関数も含めいろんな機能あるでよ、とのことです。

早速。

package AnalyzeSentence;

use strict;
use warnings;

use base qw/Exporter/;

our $WORD_SEPARATOR = qr/\s+/;
our @EXPORT_OK      = qw($WORD_SEPARATOR count_words words);

sub words {
    my $sentence = shift;
    return split $WORD_SEPARATOR, $sentence;
}

sub count_words {
    my $sentence = shift;
    return scalar words($sentence);
}

1;

なんかしらの文字(今回はスペース)でsplitして単語の数を数えるモジュール。

Test::Moreでてすてぃんぐ。

#!/usr/bin/perl
use strict;
use warnings;

use Test::More tests => 5;

my @subs = qw(words count_words);

use_ok('AnalyzeSentence', @subs);
can_ok(__PACKAGE__, 'words');
can_ok(__PACKAGE__, 'count_words');

my $sentence = 'Experience is simply the name we give our mistakes.';

my @words = words($sentence);
ok(@words == 9, 'words() should return all words in sentence');

$sentence = 'Foo Bar Baz';
my $count = count_words($sentence);

ok($count == 3, 'count_words() shoul handle simple sentences');

:use_ok():モジュールのuseとシンボルのimportの確認。 :can_ok():メソッドを呼び出せるか確認。UNIVERSAL::can。

この2つがお初。あと、useじゃなくてrequire用に、require_okってのもある。

で、p.14ではimportしたsymbolをテスト側で使いたいとき対策が書かれてる。サンプルでは$WORD_SEPARATORをimportしてそいつに区切り文字を代入してテストに使う、というもの。

use_ok('AnalyzeSentence', @subs, '$WORD_SEPARATOR') or exit;

シンボル追加。そしてテストも追加する。

$WORD_SEPARATOR = qr/(?:\s|-)+/;
@words = words($sentence);
ok(@words == 3, 'respecting $WORD_SEPARATOR, if set');

で、うまくいくと思ったテストは失敗するのであった…。

[omae@colinux]% prove t/analyze_sentence2.t                    [~/perl/test/01]
t/analyze_sentence2....Global symbol "$WORD_SEPARATOR" requires explicit package name at t/analyze_sentence2.t line 23.
Execution of t/analyze_sentence2.t aborted due to compilation errors.
### Looks like your test died before it could output anything.
t/analyze_sentence2....dubious
        Test returned status 255 (wstat 65280, 0xff00)
FAILED--1 test script could be run, alas--no output ever seen

コンパイルフェーズでは最終行に達しても$WORD_SEPARATORが無いまま。use_okではuseしない。なので、use strictに引っかかってしまう。こんなときはBEGINブロックでuse_okしてしまえとなるみたい。

BEGIN {
    my @subs = qw(words count_words);
    use_ok('AnalyzeSentence', @subs, '$WORD_SEPARATOR') or exit;
}
[omae@colinux]% prove t/analyze_sentence2.t                    [~/perl/test/01]
t/analyze_sentence2....ok
All tests successful.
Files=1, Tests=6,  0 wallclock secs ( 0.03 cusr +  0.07 csys =  0.10 CPU)

なるへそ。

あと、use_okはor exit(またはdie)してテスト全部終わらせたほうがよいよ、いろいろ面倒があるから(実行するテストの数が違ってくるとか)。だそうです。

うむ。

全然関係ないですが、このエントリーもmt-text-hatena.plプラグイン、というかText::Hatenaでハテナイズしてるんですが、スーパーpre記法が空行を無視して縮めるのはなんとかならんもんかと…。空行入れるために先頭にスペース1個入れて対応してみたけど…。