- 2012-02-09 (木) 11:00
- PHP
PHPUnitのテストケースで書き換えた値の復帰について。
テストケースでテストを記述する際に、スーパーグローバルやクラス変数を書き換えることがあるのですが、これらの値を書き換えたまま、別のテストを実行すると書き換えられた状態でテストが実行されるので、それらの値に依存した処理があるとテストが通らないことがあります。
PHPUnitでは、そういったテストをまたがって影響を及ぼすであろう値の保存、復帰を自動で行なってくれる機能があります。
スーパーグローバル
デフォルトでは、各テストメソッドを実行する前に、スーパーグローバル変数($_ENV, $_POST, $_GET, $_COOKIE, $_SERVER, $_FILES, $_REQUEST)の値をが保存されており、テストメソッド終了後にそれらの値がスーパーグローバル変数へ復帰されます。
これらの処理はsetUp()/tearDown()の外側で行なわれており、setUp()の前に値の保存、tearDown()の後に復帰されるので、スーパーグローバル変数については値の保存と復帰を自分で書く必要はありません。
下のソースでは、テスト開始前にスーパーグローバルの内容を保持しておき、実際に値の復帰が行われているかを確認しています。
なお、以下のいずれかの方法で、この機能を無効にすることもできます。
- phpunitコマンドで「–no-globals-backup」を指定
- アノテーションで「@backupGlobals disabled」を指定
- テストケースのインスタンス変数「$backupGlobals」にfalseを指定
また、インスタンス変数$backupGlobalsBlacklistに値の保存、復帰したくない変数名を連想配列で記述するとその変数だけ保存、復帰を避けることができます。
しかし、この機能を無効化するとテスト内で書き換えたスーパーグローバルの値が別のテストでも使用されてしまい、実行結果に影響を及ぼしてしまう可能性があるので、通常はデフォルトのまま有効にしておく方が良いでしょう。
クラス変数
PHP5.3以降の環境では、テスト実行時にユーザが定義しているクラスのクラス変数についてもスーパーグローバル変数と同様に値の保存、復帰を行うことができます。
ただし、デフォルトでは有効となっておらず、以下のいずれかの方法により有効となります。
- phpunitコマンドで「–static-backup」を指定
- アノテーションで「@backupStaticAttributes enabled」を指定
- テストケースのインスタンス変数「$backupStaticAttributes」に true を指定
この機能を用いると、これまでテストが困難だと思われていたSingletonパターンのクラスについて別のテストケースの影響を受けることなくテストすることができます。
下のソースでは、Sigletonで実装したクラスのクラス変数(private)の値が復元されているかを確認しています。
この処理は GlobalStateクラス(PHPUnit/Util/GlobalState.php)の backupStaticAttributes メソッドで実行されます。値の保存、復帰には Reflection が使われており、protected/private な変数についても setAccessible(TRUE) を実行して値をアクセスしています。
Reflection を使って値を取得するには分かりやすいサンプルになっているので、興味がある方はソースを読んでみて下さい。
PHPUnitは奥深い
PHPのxUnitツールとしてはデファクトスタンダードとなっているPHPUnitですが、実に多くの機能があり、まだまだ把握できていません。
全ての機能を使わずともテストは書けるのですが、今回のスーパーグローバルやクラス変数の保持、復元のように知っていればより勘弁にテストが書ける機能があります。
こういった機能を知って、より簡単に楽にテストが書けるようにしていきたいですね。PHPUnit勉強会でもやろうかな。
- Newer: blogに使える、わかりやく伝える3つの技術
- Older: 蕁麻疹のため禁酒してます
トラックバック:0
- このエントリーのトラックバックURL
- /blog/2012/02/phpunit_backup_and_restore_values.html/trackback
- Listed below are links to weblogs that reference
- PHPUnit テストケースで書き換えた値を復帰する from Shin x blog