CakePHPシェルの単体テストのやり方

CakePHPのシェルの単体テストは少々面倒くさいです。WEB表示を前提としたコントローラやコンポーネントと違ってCLIへの出力をするので、CakePHP内のリクエスト順が違います。そのためDispatcherの設定などを変えなければなりません。

ただ、深く考えずにシェルのテストをしたいだけなら、Coreのテストからソースをコピーするだけで動きます。

以下に簡単なサンプルを載せます。

### サンプル
テスト対象のシェル: **uso.php**

テストケース: **uso.test.php**

実行方法と出力結果

### 解説

uso.test.phpの先頭部分で何をやっているのかわかりづらいと思います。要はモックオブジェクトを使って、Dispatcherの書き換えと、CLIへの入出力の無効化をしています。あとはそのモックをsetUp()内で読み込んでいます。詳しいことは下記の「参考」にあるアドレスを見てください。

また、「expectAt()」というメソッドはSimpleTestのアサーションの一つです。詳しいことは[SimpleTest for PHP mock objects documentation](http://www.lastcraft.com/mock_objects_documentation.php “SimpleTest for PHP mock objects documentation”)を参考にしてください。

地味な注意ですが、expectAt()で予期している文字列は “uhouho” ではなく “uhouho**\n**”です。$this->out()は改行記号付きで標準出力するメソッドです。何回やってもfailになるのでおかしいと思い、Coreのテストを見てやっと気付きました。

### 参考
* [Unit Testing CakePHP Shells | Mark Story](http://mark-story.com/posts/view/unit-testing-cakephp-shells “Unit Testing CakePHP Shells | Mark Story”)
* [翻訳: Unit Testing CakePHP Shells | 1000g](http://blog.1000k.net/2010/07/27/cakephp%e3%81%ae%e5%8d%98%e4%bd%93%e3%83%86%e3%82%b9%e3%83%88/ “翻訳: Unit Testing CakePHP Shells | 1000g”)
* [CakePHPの典型的なリクエスト :: CakePHPの基本原則 :: マニュアル :: 1.3コレクション :: The Cookbook](http://book.cakephp.org/ja/view/898/A-Typical-CakePHP-Request “CakePHPの典型的なリクエスト :: CakePHPの基本原則 :: マニュアル :: 1.3コレクション :: The Cookbook”)
* [SimpleTest for PHP mock objects documentation](http://www.lastcraft.com/mock_objects_documentation.php “SimpleTest for PHP mock objects documentation”)


“CakePHPシェルの単体テストのやり方” への3件のフィードバック

  1. Shellクラス内のメソッドをテストしたかったので大変参考になりました。
    uso.test.php の setUp()メソッドで、KwrankShell となっているところは UsoShell にするのが正しいようですね。

  2. ご指摘ありがとうございます。修正しました。

    こんな記事書いておいてなんですが、最近はコマンドラインスクリプトをフレームワークを用いて作ることは辞めました。ディスパッチャの解釈や、モックを作ったりが面倒だからです。それに、コピペでないと再現できないおまじないは鬱陶しいですしね。

    MVCの考え方はCLIアプリでもそっくり適用できそうなもんですが、現状のフレームワークはWEB表示のことしか考えていないようです。

  3. I have some function in Console/Command directory and i want to test these functions.Any help ?

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

次のHTML タグと属性が使えます: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">