テスト駆動開発 (TDD: Test Driven Development)動作するきれいなコード (Clean code that works) を書くことを目的とするソフトウェア開発手法であり、プログラム本体のコードよりも先にテストコードを書くという大きな特徴を持っています。筆者らは日常的に TDD を使った開発を行っており、Piece Framework のプロダクトの多くは TDD を使って書かれたものです。

TDD を実践するためにはテストを自動的に実行するための環境が必須であり、テストをすばやく実行できることが開発効率向上の重要なポイントとなります。Stagehand_TestRunner は、この点に着目して開発された Piece Framework のプロダクトです。今回は以前の記事「プロジェクトローカルな PEAR 環境を構築する」で構築した環境を利用し、プロジェクトローカルな Stagehand_TestRunner の使い方を簡単な例とともに解説します。

MATSUFUJI Hideharu

プロジェクトローカルな PEAR 環境を構築する

Stagehand_TestRunnerPEAR パッケージとして提供されているため、プロジェクトローカルな Stagehand_TestRunner の実行環境を構築するためには、プロジェクトローカルな PEAR 環境を構築する必要があります。構築方法については「プロジェクトローカルな PEAR 環境を構築する」をご覧ください。以下、この環境を前提に話を進めていきます。

Stagehand_TestRunner のインストール

Stagehand_TestRunnerPHPUnit, SimpleTest, PHPSpec といったテスティングフレームワークを使用して書かれたテストコードを自動的に実行するためのコマンドラインプログラムを提供します。今回はテスティングフレームワークとして PHPUnit を使用します。インストールするパッケージは以下のとおりです。

パッケージ用途
Stagehand_TestRunnerテストの自動実行と結果表示
PHPUnitテスティングフレームワーク
Stagehand_Autoloadクラスのオートローディング

これらをインストールするためのコマンドは以下のようになります。

bin/lpear channel-discover pear.phpunit.de
bin/lpear channel-discover pear.piece-framework.com
bin/lpear install phpunit/PHPUnit
bin/lpear install piece/Stagehand_TestRunner
bin/lpear install piece/Stagehand_Autoload-beta

Stagehand_TestRunner でテストを実行する

最初に 1 つめのテストコードを用意します。

tests/MyApp/FooTest.php
<?php
class MyApp_FooTest extends PHPUnit_Framework_TestCase
{

    /**
     * @test
     */
    public function trueを返す
    {
        $foo = new MyApp_Foo();

        $this->assertTrue($foo->bar());
    }
}

テストを実行するためには Stagehand_TestRunner が提供するコマンド testrunner を実行する必要があります。testrunnerPHPUnit 用のコマンドですが、SimpleTest, PHPSpec 用のコマンドもそれぞれ testrunner-st, specrunner として提供されています。では testrunner を実行しましょう。

$ bin/testrunner

Warning: require_once(Stagehand/TestRunner.php): failed to open stream: No such file or directory in /path/to/myapp/bin/testrunner on line 41

Fatal error: require_once(): Failed opening required 'Stagehand/TestRunner.php' (include_path='.:/usr/share/php:/usr/share/pear') in /path/to/myapp/bin/testrunner on line 41

どうやら実行に失敗したようです。この環境はプロジェクトローカルなものですからシステム全体の include_path の構成に含まれていないとしても不思議ではありません。include_path をこの環境専用に構成すれば問題は解決します。それはどこでどうすればいいのでしょうか?

-p オプションで include_path を構成する

Stagehand_TestRunner には、テストコードの収集・実行よりも前に読み込ませたい PHP スクリプトを指定するための -p オプションがあります。include_path の構成に -p オプションを使用することで、Stagehand_TestRunner 自体を含めたあらゆるクラスを特定の環境からロードすることができます。

include_path を構成するための PHP スクリプト tests/prepare.php は以下のようになります。

tests/prepare.php
<?php
error_reporting(E_ALL | E_STRICT);

set_include_path(realpath(dirname(__FILE__) . '/../src') . PATH_SEPARATOR .
                 realpath(dirname(__FILE__) . '/../imports/PEAR/src') . PATH_SEPARATOR .
                 realpath(dirname(__FILE__) . '/../imports/PEAR')
                 );

require_once 'PHPUnit/Framework.php';
require_once 'Stagehand/Autoload/PEAR.php';

今回はクラスのオートローディングStagehand_Autoload を使用するため、最後の行で Stagehand/Autoload/PEAR.php をロードしています。

では testrunner コマンドを実行します。

$ bin/testrunner -p tests/prepare.php 
PHPUnit 3.3.16 by Sebastian Bergmann.



Time: 0 seconds


OK (0 tests, 0 assertions)

今度はコマンドの実行はエラーになりませんでしたが、先ほど作成したテストが実行されていないようです。これは -R (再帰的なテストの実行) オプションか -a (autotest) オプションを指定しない限り、testrunner コマンドは単一のテストファイルを実行するか何も実行しないかのいずれかの動作を行うためです。

再帰的なテストの実行

では、-R オプションとともに tests ディレクトリを指定し、再帰的なテストの実行を行います。

$ bin/testrunner -p tests/prepare.php -R tests
PHPUnit 3.3.16 by Sebastian Bergmann.


Fatal error: Class 'MyApp_Foo' not found in /path/to/myapp/tests/MyApp/FooTest.php on line 10

今度はエラーにはなりましたが、テストコードは読み込まれたことがわかります。ではプロダクトコードを用意しましょう。

src/MyApp/Foo.php
<?php
class MyApp_Foo
{
    public function bar()
    {
        return true;
    }
}

再びテストを実行します。

$ bin/testrunner -p tests/prepare.php -R tests
PHPUnit 3.3.16 by Sebastian Bergmann.

.

Time: 0 seconds

MyApp_Foo
 - Trueを返す

OK (1 test, 1 assertion)

今度はテストの実行が行われ無事にパスすることができました。次に 2 つめのテストコードを用意し、同じコマンドですべてのテストが実行されるか確認しましょう。

tests/MyApp/BazTest.php
<?php
class MyApp_BazTest extends PHPUnit_Framework_TestCase
{

    /**
     * @test
     */
    public function falseを返す()
    {
        $baz = new MyApp_Baz();

        $this->assertFalse($baz->qux());
    }
}
src/MyApp/Baz.php
<?php
class MyApp_Baz
{
    public function qux()
    {
        return false;
    }
}
$ bin/testrunner -p tests/prepare.php -R tests
PHPUnit 3.3.16 by Sebastian Bergmann.

..

Time: 0 seconds

MyApp_Baz
 - Falseを返す

MyApp_Foo
 - Trueを返す

OK (2 tests, 2 assertions)

期待どおりに同じコマンドですべてのテストが実行されました。なお、このコマンドライン bin/testrunner -p tests/prepare.php -R tests は異なるプロジェクトであっても共通で使えるため、好みのオプションとともにエイリアスとして登録しておくと便利です。

Stagehand_TestRunner で TDD を快適にしよう

今回の記事では、プロジェクトローカルな PEAR 環境Stagehand_TestRunner を使う方法をご紹介しました。前提条件であるプロジェクトローカルな PEAR 環境さえあれば、特に難しくないことがわかっていただけたでしょう。

Stagehand_TestRunner には結果の色付けを行う -c オプションや、指定されたディレクトリ以下のファイルの追加、削除、変更を監視し、何か変化があれば自動的にテストを実行する -a オプション、詳細な進捗リポートを出力する -v オプションなど、TDD を実践するにあたって便利な機能が用意されています。TDD のお供に是非使ってみてください。

使用したソフトウェアのバージョン

Stagehand_TestRunner2.6.2
PHPUnit3.3.16
Stagehand_Autoload0.1.0

参考文献

トラックバック(0)
  • このブログ記事のトラックバックURL:
コメント