Born Too Late

Yuya's old tech blog.

PHPUnit の実行を自動化する 3 つの方法

2011-08-16 03:07:11

皆さん, ユニットテスト書いてますか.

TDD (テスト駆動開発) によるプログラミングは本当に楽しいものですが, コマンドをいちいち手動で実行するのは面倒ですよね.
テストを自動化しているんだから, その実行も自動化したいですよね.

この記事では, 私が仕事や趣味で使っている PHPUnit を例に, テストの実行の自動化について紹介します.
PHPUnit の, としてはいますが, 他の言語で使えるテクニックもあります.

なお, ここでの自動化は開発しながらの自動実行のことで, CI (継続的インテグレーション) の話は出てきません.

その前に...

私の開発時のターミナルは以下のようになっています.

[caption id="attachment_1298" align="alignnone" width="300" caption="開発時のターミナル"]開発時のターミナル[/caption]

GNU screen での画面分割を利用して, 左半分をソースコードに, 右上をテストコードに, 右下をテストの実行に使っています.
これは作業の途中でいろいろと変動しますが, 右下ではほぼ常にテストが自動実行されるようになっています.
(ターミナルの透明化を利用してバックグラウンドでニコ動を観ることもできますね)

この小さい画面での実行を前提に, 紹介していきます.

シェルスクリプトを利用する

まずはとにかく, 決められたコマンドを定期的に実行しましょう.

コマンドを定期的に実行, というと watch コマンドを思い浮かべる人が多いと思いますが, これは使いません.
何故か, ターミナル上の色が無効化されてしまい, レッドやグリーンがわかりづらいからです.

色の使える watch は無いか, と探した所, superuser という Q&A サイトにちょうどいいものがありました.
bash watch command with colors preserved

ここへの書き込みを参考に, 以下のようなシェルスクリプトを用意しました.

適当な場所に保存して, chmod +x して実行権限を与えたら, 以下のように使用することができます.

$ ./watch2 phpunit --colors

これで, 出力の色づけを維持したまま, PHPUnit を 2 秒間のインターバルで起動し続けることができるようになりました.

プロジェクトの規模によっては全てのテストを実行するのに時間がかかることもあるので, そういうときは特定のファイルを指定しましょう.

$ ./watch2 phpunit --colors tests/Foo/BarTest.php

今自分が作業しているファイルだけを指定することで, フィードバックを素早く的確に得られるようになります.
コマンドの指定は手動ですが, 環境の用意はとても楽なのでよしとしましょう.

Stagehand_TestRunner を利用する

Stagehand_TestRunner は, PHPUnit だけでなく Lime や PHPSpec にも対応したテストランナーです.
(2011-08-16 14:00 追記: Lime への対応は勘違いでした. @heavenshell さんご指摘ありがとうございました.)

インストールについては本家の Wiki を参照しましょう.
テスト駆動開発のためのテストランナー

PHPUnit 本家よりも優れた表示が特徴です.

[caption id="attachment_1303" align="alignnone" width="300" caption="Stagehand_TestRunner による実行結果"]Stagehand_TestRunner による実行結果[/caption]

この出力形式は testdox と呼ばれるもので, テストメソッド名を英文っぽく表示してくれます.
testdox を表示する機能自体は PHPUnit にもあります (--testdox オプション) が, Stagehand_TestRunner を使うと色づけされるので, よりわかりやすくなります.

Stagehand_TestRunner には他にも様々な機能がありますが, ここで紹介するのはディレクトリの監視によるテストの自動実行です.

これを phpunit.xml として保存して, 同じディレクトリ上で以下のコマンドを実行します.

$ phpunitrunner --phpunit-config=phpunit.xml -cRa

c が色づけ, R が指定ディレクトリ (phpunit.xml で指定していますね) 以下を再帰的に, a が自動実行のためのオプションです.

これで, ディレクトリに変更のあったときだけテストが実行されるようになりました.

実行対象のテストを正規表現で絞り込んだりすることもできますが, それらの詳細については以下の Wiki が参考になります.
Stagehand_TestRunner ユーザーガイド

watchr を利用する

最後に紹介するのは, 最近一番よく使っている方法です.
watchr はファイルの変更を監視するツールで, 検出時にあらゆる処理をフックさせることができます.

watchr は Ruby 製のツールなので, 処理は Ruby で書く必要があります.
といっても, 簡単な正規表現が書ければ充分なので, Ruby 未経験でも問題無いでしょう.

インストールについては Rubygems をインストールして gem install watchr するだけです.

watchr の設定ファイルとして, 以下のようなものを用意します.

これは src ディレクトリのソースコードの変更時に対応するテストを実行すること, テストコードの変更時にはそのファイル自身のテストを実行すること, を設定しています.

そして以下のようなコマンドを実行することで, 監視状態に入ります.

$ watchr phpunitrunner.watchr

前提として, ソースコードが src/Foo.php であればテストコードは tests/FooTest.php というように, 命名規則にそったファイル名になっていることが必要です.

変更のあったときにだけ, そのファイルだけテストが実行されるので, 素早く確実にフィードバックを得ることができます.

また, Ctrl + \ を押すことで, 全てのテストを実行することもできます.

注意としては, 監視対象のファイルの読み込みが watchr の起動時なので, 例えば途中で新規に追加したファイルは監視対象に入っていないことです.
ある程度開発が進んで, 作業のメインが既存ファイルの編集になったときに, より高い効果を発揮するでしょう.

まとめ

テストだけでなく, その実行まで自動化することで開発にリズムが生まれ, フロー状態に入りやすくなります.
開発効率を上げ, 楽しい TDD ライフを送りましょう.

その他, オススメのツールややり方などありましたら, 是非 @yuya_takeyama まで教えてください.