PerlのTest::Specを使ってtestプログラムを作成する。

# 概要
Test::Specを使ってtestプログラムを作成しました。

# Test::Specとは
https://metacpan.org/pod/Test::Spec
RubyのRspecっぽくテストを書くことができるモジュールです。

# はじめに
まずはこんな感じに書いてみましょう。

```test.t
use Test::Spec;

# describe: テストの塊みたいなのもの
describe 'testをします。' => sub {

    # it: テストを定義している所
    it 'ok' => sub {

        # testを行う
        ok 1;
    };
};

# runtestsでtestを実行する
runtests unless caller;
```

test.tを実行します。

```
$ perl test.t
ok 1 - testをします ok
1..1
```

testが実行されました。
このようにtestプログラムを作成することができます。

# describeについて
describeはテストの塊みたいなのもので、testをまとめることが出来ます。

```test2.t
use Test::Spec;

describe 'testをします' => sub {
    my $a = 1;
    my $b = 2;

    describe 'aのテスト' => sub {
        it '値が1である' => sub {
            is $a, 1;
        };
    };

    describe 'bのテスト' => sub {
        it '値が2である' => sub {
            is $b, 2;
        };
    };

};

runtests unless caller;
```

これを実行すると。

```
$ perl test2.t
ok 1 - testをします aのテスト 値が1である
ok 2 - testをします bのテスト 値が2である
1..2
```

こんな感じにtestを分けて見やすく書くことができるようになります。

# itについて
itはテストを定義している所です。
itの中にtestを書くことで、どこで評価しているか分かりやすくなります。

```test3.t
use Test::Spec;

my $a = 1;

it '値が1である' => sub {
    is $a, 1;
};

runtests unless caller;
```

```
$ perl test3.t
ok 1 - 値が1である
1..1
```

# before と after
beforeとafterを使うと、テストを実行をする前に実行するコードを定義することができます。
主に使われるのは以下の4つです。

```
# 全てのテストで一回だけ呼ばれる。
before all
after all

# 各テストで毎回呼ばれる。
before each
after each
```

```test4.t
use Test::Spec;

describe 'testをします' => sub {
    before all => sub {
        warn 'before all';
    };
    
    after all => sub {
        warn 'after all';
    };

    before each => sub {
        warn 'before each';
    };
    
    after each => sub {
        warn 'after each';
    };

    it 'test 1-1' => sub {
        ok 1;
    };

    describe 'test 1-2' => sub {
        it 'test 2-1' => sub {
            ok 1;
        };

        it 'test 2-2' => sub {
            ok 1;
        };
    };
};

runtests unless caller;
```

※分かりやすいように改行を入れています。

```shell

$ perl test4.t
before all at test4.t line 6.

before each at test4.t line 14.
ok 1 - testをします test 1-1
after each at test4.t line 18.

before each at test4.t line 14.
ok 2 - testをします test 1-2 test 2-1
after each at test4.t line 18.

before each at test4.t line 14.
ok 3 - testをします test 1-2 test 2-2
after each at test4.t line 18.

after all at test4.t line 10.
1..3
```

ちなみに、describeをネストして使用すると、　実行順序は以下のようになります。

```test5.t
use Test::Spec;

describe 'testをします' => sub {
    before all => sub {
        warn 'before all 1';
    };
    
    after all => sub {
        warn 'after all 1';
    };

    before each => sub {
        warn 'before each 1';
    };
    
    after each => sub {
        warn 'after each 1';
    };

    it 'test 1-1' => sub {
        ok 1;
    };

    describe 'test 1-2' => sub {
        before all => sub {
             warn 'before all 2';
        };
        
        after all => sub {
            warn 'after all 2';
        };

        before each => sub {
            warn 'before each 2';
        };
        
        after each => sub {
            warn 'after each 2';
        };

        it 'test 2-1' => sub {
            ok 1;
        };

        describe 'test 2-2' => sub {
            before all => sub {
                 warn 'before all 3';
            };
            
            after all => sub {
                warn 'after all 3';
            };

            before each => sub {
                warn 'before each 3';
            };
            
            after each => sub {
                warn 'after each 3';
            };

            it 'test 3-1' => sub {
                ok 1;
            };

            it 'test 3-2' => sub {
                ok 1;
            };
        }; 
    };
};

runtests unless caller;
```

※分かりやすいように改行、段落、コメントを入れています。

```shell
$ perl test5.t
# befor all 1
before all 1 at test5.t line 6.
    before each 1 at test5.t line 14.
        ok 1 - testをします test 1-1
    after each 1 at test5.t line 18.

    before each 1 at test5.t line 14.
        # befor all 2
        before all 2 at test5.t line 27.

        before each 2 at test5.t line 35.
            ok 2 - testをします test 1-2 test 2-1
        after each 2 at test5.t line 39.
    after each 1 at test5.t line 18.

    before each 1 at test5.t line 14.
        before each 2 at test5.t line 35.
            # befor all 3
            before all 3 at test5.t line 48.

            before each 3 at test5.t line 56.
                ok 3 - testをします test 1-2 test 2-2 test 3-1
            after each 3 at test5.t line 60.
        after each 2 at test5.t line 39.
    after each 1 at test5.t line 18.

    before each 1 at test5.t line 14.
        before each 2 at test5.t line 35.
            before each 3 at test5.t line 56.
                ok 4 - testをします test 1-2 test 2-2 test 3-2
            after each 3 at test5.t line 60.
        after each 2 at test5.t line 39.
    after each 1 at test5.t line 18.

after all 1 at test5.t line 10.
after all 2 at test5.t line 31.
after all 3 at test5.t line 52.
1..4
```

# 最後に
今回はよく使われそうなものを紹介しました。
他にもいろいろ便利な機能があるので試してみてください。