ziguzagu.org

もっと便利なok()

PerlTestingのChapter1最終戦です。

ok()って基本中の基本ですがやっぱり不便です。いろんなテストがあるのに条件を1個に縮めないといけないんですもの。でも、Test::Moreにはok()の代わりに使えるイケてる関数がいくつかあります。

まずはテストコード。

#!/usr/bin/perl
use strict;
use warnings;
use Test::More tests => 4;

use_ok('Greeter') or exit;

my $greeter = Greeter->new(name => 'Emily', age => 21);
isa_ok($greeter, 'Greeter');

is($greeter->age(), 21,
   'age() should return age for object');
like($greeter->greet(), qr/Hello, .+ is Emily!/,
     'greet() should include object name');

:isa_ok:指定した名前or型のオブジェクトorリファレンスかをテスト。UNIVERSAL::isa()。 :is:ok()の別名みたいなもん。2つの引数がeqかどうかテスト。 :like:またしてもok()の別名みたいなもん。1つ目の引数が2つ目の引数の正規表現にマッチするかテスト。

is/likeに関してはokでもええやん、と思ったけど、自分で条件式書くよりは見た目わかりやすいかも。

テストするモジュールは単純な挨拶モジュール。

package Greeter;

use strict;
use warnings;

sub new {
    my ($class, %args) = @_;
    bless \%args, $class;
}

sub name {
    return shift->{name};
}

sub age {
    return shift->{age};
}

sub greet {
    return "Hello, my name is " . shift->name() . "!";
}

1;

失敗テスト追加して実行してみる。

is($greeter->age(), 54,
   'Emily became a older.');
like($greeter->greet(), qr/Hello, .+ is John!/,
     'Emliy renamed to John.');

Emliyは一気に年をとり、Johnと改名しました。

[omae@colinux]% prove -v greeter.t                             [~/perl/test/01]
greeter....1..6
ok 1 - use Greeter;
ok 2 - The object isa Greeter
ok 3 - age() should return age for object
ok 4 - greet() should include object name
not ok 5 - Emily became older.

###   Failed test 'Emily became older.'
###   in greeter.t at line 16.
###          got: '21'
###     expected: '54'
not ok 6 - Emliy renamed John.

###   Failed test 'Emliy renamed John.'
###   in greeter.t at line 18.
###                   'Hello, my name is Emily!'
###     doesn't match '(?-xism:Hello, .+ is John!)'
### Looks like you failed 2 tests of 6.
dubious
        Test returned status 2 (wstat 512, 0x200)
DIED. FAILED tests 5-6
        Failed 2/6 tests, 66.67% okay
Failed Test Stat Wstat Total Fail  Failed  List of Failed
-------------------------------------------------------------------------------
greeter.t      2   512     6    2  33.33%  5-6
Failed 1/1 test scripts, 0.00% okay. 2/6 subtests failed, 66.67% okay.

あ、失敗結果がok()よりわかりやすいですな。なるほどこんなメリットが。ok()で書いた失敗テストも追加してみる。

ok($greeter->age() eq '54',
   'Emily became a older.');
ok($greeter->greet() =~ m/Hello, .+ is John!/,
     'Emliy renamed to John.');

結果は、

not ok 5 - Emily became a older.

###   Failed test 'Emily became a older.'
###   in greeter.t at line 16.
###          got: '21'
###     expected: '54'
not ok 6 - Emliy renamed to John.

###   Failed test 'Emliy renamed to John.'
###   in greeter.t at line 18.
###                   'Hello, my name is Emily!'
###     doesn't match '(?-xism:Hello, .+ is John!)'
not ok 7 - Emily became a older.

###   Failed test 'Emily became a older.'
###   in greeter.t at line 21.
not ok 8 - Emliy renamed to John.

###   Failed test 'Emliy renamed to John.'
###   in greeter.t at line 23.

これはok()でOK(イタイ…)とか言ってちゃダメですな。is/likeには否定バージョンのisnt/unlikeもあったりするのでそちらもよろしこ。

ということでChapter1終了。

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