Mobile Factory Tech Blog

技術好きな方へ!モバイルファクトリーのエンジニアたちが楽しい技術話をお届けします!

Perlのテストモジュールの紹介

この記事は、モバイルファクトリーAdvent Calendar 2018 23日目の記事です。
前日の記事は、id:masasuzさんの モバイルファクトリーのインフラアーキテクチャ でした。

こんにちは、id:yumlonneです!
最近、テストの重要性をひしひしと感じているので、テストについての記事を書くことにしました。

他の記事でも紹介されていますが、モバイルファクトリーの主要プログラミング言語はPerlです。
Perlは動的型付け言語であり、プログラマがデータ型を管理しなければならないため、非常にテストが重要です。

今回は、最近個人的に注目しているテストモジュールを2つ紹介します。

Test::Doctest

Test::Doctestは、Python由来のテストモジュールです。
その名の通り、ドキュメント内にテストを仕込むことができます。

ここでいうドキュメントとは、平たく表現すれば「ソースコード内の関数説明などに用いられるコメント」のことです。
Perlでは#を使ってコメントを書くことができますが、関数説明にはPODを使います。

Test::Doctestは、POD内に埋め込まれたテストを実行します。

使用例

コード

pod内の>>>の後ろにコードを書き、下の行に期待する結果を書きます。

package Hoge;
use strict;
use warnings;
use utf8;

=encoding utf8

=head1 METHODS

=over

=item plus1

    数値に1を足してくれる関数

    >>> plus1(30)
    31

    >>> plus1(-1)
    0

=back

=cut
sub plus1 {
    my $n = shift;
    return $n + 1;
}

1;

テスト

コマンドラインからテストを実行する例を載せますが、.tファイルにすることもできます。
詳細はSYNOPSISを参照してください。

$ perl -MTest::Doctest -e run lib/Hoge.pm
1..2
ok 1 - plus1 1/2 (lib/Hoge.pm, 16)
ok 2 - plus1 2/2 (lib/Hoge.pm, 19)

Test::Doctestまとめ

以下に私なりの長所・短所をまとめました。
短所を認識し、複雑なものは別のファイルに書くなどの対応をすれば、十分に使う価値のあるモジュールだと思います。

長所

  • ソースコードと同一のファイルにテストが書けるため、敷居が低い
  • 関数の入出力例を示すことができる
  • DoctestのためにPODを書くというモチベーションが生まれる

短所

  • 複雑な関数や文字列での表現が難しい(あるいは長くなる)入出力データを扱うのが難しい
  • 書きすぎるとソースコードの見通しが悪くなる

Test::RandomCheck

Test::RandomCheckは、Haskell由来のテストモジュールです。
このテストモジュールには大きな特徴が2つあります。

  • テストデータをモジュールがランダムに生成する
  • テストするのは関数の性質

使い所は限られていますが、非常に簡単にテストができます。

使用例

コード

ここでも先程テストしたplus1関数のテストをします。

package Hoge;
use strict;
use warnings;
use utf8;

sub plus1 {
    my $n = shift;
    return $n + 1;
}

1;

テスト

use Test::RandomCheck;
use Test::RandomCheck::Generator;
use Test::More;

use Hoge;

# 受け取りたい引数の型
my $arg_type = integer;

random_ok {
    # ここでinteger型の値を受け取れる
    my $arg = shift;

    # plus1の性質をチェック
    Hoge::plus1($arg) == $arg + 1;
} $arg_type;

done_testing;

テスト結果

$ perl -Ilib t/randomcheck,t
ok 1
1..1

テストの結果の出力は非常に寂しいものの、この例ではrandom_okブロックは様々な整数値で202回実行されていました。

Test::RandomCheckまとめ

以下に私なりの長所・短所をまとめました。
使い所は難しいですが、うまく使えればとてもパワフルなモジュールだと思います!

長所

  • テストデータを考える作業をスキップできる
  • 関数が持つ性質を表明できる(reverseした配列をreverseするともとに戻るなど)

短所

  • 実験的なモジュールである
  • テストデータがランダムであるため、失敗したテストケースの特定が難しい(Haskellではテストデータを再現できる)
  • 汎用的な関数以外はテストしにくい

おわりに

今回はPerlのテストモジュールを2つ紹介しました。
テストを充実させるために、まずはテストを楽しむことが重要だと思っています。
皆さんもぜひ、紹介したテストモジュールなどを使って、テストを楽しんでみてはいかがでしょうか!

明日はid:Carimaticsさんです。お楽しみに!!