TDDモジュラノックスを持つperlscript ( pwc - 118 )

4850 ワード

Perlは強いテスト文化を持っている言語です.あなたがどんなモジュールでもリリースするとき、それは自動的に、そして、無料でシステムとオペレーティングシステムとPerl版の巨大な多様性でテストされます.
Perlはまた、大きなテストツールをテストしています.
テスト駆動開発(TDD)スタイルで新しいモジュールを書くことは非常に可能です、そして、私が彼らを連れて行くために時間を脇に置いたとき、Perl毎週挑戦に取り組む私の好ましい方法です.あなたがすることができることは、「変調」を通してTDDスクリプト自体です.
今週の課題は、あなたが提供している番号がバイナリのPalindromeであるかどうかを示すスクリプトです.
これを可能にするには、スクリプト内のすべてのコードをサブ(例えばrun ())でラップできます.それから、テストスイートからではなく、Perlからコードが呼び出されているときだけ、そのサブを呼び出します.しかし最初にテストから始めたい.
use Test::More;

require_ok('./ch-1.pl');

done_testing;

これは標準のtest ::moreモジュールを使います.このテストはスクリプト自体を作成するまで失敗します.
私はスクリーンに出力するスクリプト(stdout)を作成しているので、コマンドの出力をテストしたいので、test ::outputモジュールを使います.
use Test::More;
use Test::Output;

require_ok('./ch-1.pl');

stdout_is { &run() }
    'foo',
    'Dumb test to see if the test works';

done_testing;

そこでスクリプトを拡張して次のようにします.
__PACKAGE__ ->run() unless caller;

sub run {
    print "foo";
}

1;

ここから、我々はテストの安全性を持っている間、アウトゴールに向かって小さなステップを取ることができます.それで、テストは、このようにより賢明になるかもしれません:
use Test::More;
use Test::Output;

require_ok('./ch-1.pl');

stdout_is { &run(5) }
    'xxxxx',
    '5 is a palindrome';

done_testing;

これはスクリプトが希望する形式で所望の答えを与えることを確認する小さなテストです.この場合、私はすでにTDDスタイルでモジュールをコード化しました;したがって、これは本当にコードの配線をテストすることです.バージョン1は次のようになります.
__PACKAGE__ ->run() unless caller;

use lib './lib';
use Binary::Palindrome;

sub run {
    my $n = $ARGV[0] || shift;

    my $bp = Binary::Palindrome->new;

    print $bp->is_palindrome($n);
}

1;

だからこれはまだ私は実際に一歩一歩でした.私は実際にちょうど使用ラインを追加し、すべてが同じままだったかどうかをテストするために実行します.私は多くの方法をテストを使用します私がtypoまたは単純な構文エラーを加えなかったことを確認してください.私は単純な間違いをスポッティングので、小さな手順を取る.まあ簡単.
私の$ n = $ argv [ 0 ]行は、コマンドライン(最初のarg、別名$ argv [ 0 ])またはシフトからのテストからのスカラーからサブハンドル入力をする方法です.
上記の状況では、“XXXXX”を探しているので、テストは失敗するはずですが、コード“1”を返すことを知っています.それで、テストは失敗して、私がokであると私に言います.それで、テストを変更することができます.
stdout_is { &run(5) }
    '1',
    '5 is a palindrome';

そして、これは通過します、次に、我々は本当のふるまいを確認したいので、テストは以下になります
stdout_is { &run(5) }
'1 as binary representation of 5 is 101 which is Palindrome.',
    '5 is a palindrome';

これはもちろん失敗するので、このテストに合格するためにスクリプトを変更させてください.
__PACKAGE__ ->run() unless caller;

use lib './lib';
use Binary::Palindrome;

sub run {
    my $n = $ARGV[0] || shift;

    my $bp = Binary::Palindrome->new;
    if ( my $res = $bp->is_palindrome($n) ) {
        print "$res as binary representation of $n is ",
            $bp->represent_as_binary($n), " which is Palindrome.";
    }
}

1;

これにより、次のテストを追加できます.
stdout_is { &run(4) }
'0 as binary representation of 4 is 100 which is NOT Palindrome.',
    '4 is NOT a palindrome';

これにより、コードが追加されます.
    if ( my $res = $bp->is_palindrome($n) ) {
        print "$res as binary representation of $n is ",
            $bp->represent_as_binary($n), " which is Palindrome.";
    }
    else {
        print "$res as binary representation of $n is ",
            $bp->represent_as_binary($n), " which is NOT Palindrome.";
    }

これを加えてテストパスが変わります.それで、我々は良い場所にいます.
これは少し工夫された例であり、多くの改善があります.しかし、私は今から固体の基地を動作している.これは私の好きな仕事のスタイルです.それを多分TDDと同様に行動駆動開発(BDD)と考えてください.または、おそらくこれは“統合テスト”、あるいは“エンドツーエンドテスト”我々が構築している与えられたとして記述することができます.私は、私のTDD/BDDの純度の用語についてはうるさいです.
個人的には、自分の開発を容易にし、より信頼性の高いツールを目指しています.
私がこれをコード化したとき、私はTDDモジュール自体をしました.
スクリプトを実行していないので最初にテストを行い、モジュールのデザインに影響を与えました.スクリプトは複雑であり、スクリプト内の両方のメソッドを使用しているので、コードは効率的ではありません.また、isCount Palindromeメソッドでは、RepresentRadise ASHINバイナリを使用します.それが副作用を持っているならば、これは悪いです;または、それが遅いならば.
次のステップは、データ構造を結果とバイナリ表現で返す3番目のメソッドを作成することです.これはより効率的です私はスクリプトのテキストの構造を「プレゼンテーション層」として残すでしょう.そして、モジュールを少しクリーナーにしますマイルが変わるかもしれませんが.完全な答えを返すメソッドは、スクリプト(細いコントローラ)で非常にきちんとしています.
してくださいチェックアウトは、毎週ウィークリーチャレンジgitレポで完全なコードですhttps://github.com/manwar/perlweeklychallenge-club/tree/master/challenge-118/lance-wicks/perl ).
そして、あなたが質問をするならば、私にメッセージを送ってください.
タグ:perlweeklychallenge tdd