Subscribed unsubscribe Subscribe Subscribe

最近のテストの書き方

use strict;
use warnings;
use utf8;

use Test::More;

my $user = create_user;
$user->do_something1;
$user->do_something2;

subtest 'fetch_something1 が A を返すこと' => sub {
    is $user->fetch_something1, 'A';
};

subtest 'fetch_something2 が B を返すこと' => sub {
    is $user->fetch_something2, 'B';
};

done_testing;

$user object に対して何らかの準備をして順に fetch_something1, fetch_something2 のテストを書いてしまうことがある。たいていめんどくさい時とか、最初は fetch_something1 のテストしかないのに、fetch_something2 も実装することになってこういう風に書いてしまう気がする。

でも、これだと $user object に fetch_something1 の処理をした後に fetch_something2 の処理をすることになるので、テストにならない時がある。
なので、

use strict;
use warnings;
use utf8;

use Test::More;

subtest 'fetch_something1 が A を返すこと' => sub {
    my $user = prepare();
    is $user->fetch_something1, 'A';
};

subtest 'fetch_something2 が B を返すこと' => sub {
    my $user = prepare();
    is $user->fetch_something2, 'B';
};

sub prepare {
    my $user = create_user;
    $user->do_something1;
    $user->do_something2;
    $user;
}

done_testing;

なるべくこういう感じて、同列の subtest を一個消しても問題ないように書いてます。
ただ、subtest を順に並べると分かりやすいので subtest の中の subtest はそういうふうに書くことは多いです。
下の例も一番上と問題は変わらないけど、とりあえず一層目の subtest 同士が依存してるとめんどくさいことが多いかなという印象。

use strict;
use warnings;
use utf8;

use Test::More;

subtest 'fetch_something1 が A を返すこと' => sub {
    my $user = prepare();
    is $user->fetch_something1, 'A';
};

subtest 'something2 周りの処理' => sub {
    my $user = prepare();

    subtest 'fetch_something2 が A を返す' => sub {
        is $user->fetch_something2, 'B';
    };

    subtest 'その後に something2 は 1 を返す' => sub {
        is $user->something2, 1;
    };
};

sub prepare {
    my $user = create_user;
    $user->do_something1;
    $user->do_something2;
    $user;
}

done_testing;