Laravel + PHPUnit + PHPSpec

ChainZ(クリエイター)
いろいろやってます。

PHPプロジェクトのテスト

PHPのテストによく使われているのはPHPUnitとPHPSpecです。基本的にPHPUnitはすべてのテストをカバーできますが、自分はPHPSpecを優先にして、PHPUnitがバックアップっていう感じで使ってます。PHPSpecはオブジェクトの挙動を検証するには得意だが、サイトのリスポンスなどのテストはちょっと苦手です。

Laravel5のテスト

LaravelではすでにUnitテスト実装済みです。PHPUnitについては公式サイトを参考してください: http://laravel.com/docs/5.0/testing 

PHPSpecを使う

LaravelのEloquentモデルはちょっと特殊で、PHPSpecを使うには面倒なセッティングが必要なので、phpspec-laravelを使うのをおすすめします: https://github.com/BenConstable/phpspec-laravel 

phpspec-laravelを使う

composer.jsonファイルに

{
"require-dev": {
"benconstable/phpspec-laravel": "~2.0@dev"
}
}

を追記します。 phpspec.yml

extensions:
- PhpSpec\Laravel\Extension\LaravelExtension
laravel_extension:
migrate_db: true

を追記します。composer updateを忘れずに!

すると、./vendor/bin/phpspecからPHPSpecコマンドが実行できます。

PHPSpecを書いてみる

下記のコマンドでモデルを作成します。

php artisan make:model Node

すると、app/Node.phpが作成されます。次に、

./vendor/bin/phpspec describe App/Node

を叩いて、App\Nodeのテストファイルを作成します。spec/NodeSpec.phpを開いて、

use PhpSpec\ObjectBehavior;
use Prophecy\Argument;

use PhpSpec\Laravel\EloquentModelBehavior;

にして、ObjectBehaviorのかわりにEloquentModelBehaviorを継承します:

class NodeSpec extends EloquentModelBehavior

そして、下記のコードを追加します:

public function it_has_type_of_node()
{
$this->getType()->shouldBe('node');
}

./vendor/bin/phpspec runします。

下記の情報が表示されます(PHPSpecのバージョンによって若干変わることがあります)

- it has type of node
method App\Node::getType not found.

App\NodeにはgetType()メソードがないってPHPSpecが

Do you want me to create `App\Node::getType()` for you?
// `App\Node::getType()`を作成してもよろしいですか?

聞いてくるので、Yで返答すれば、app\Node.phpに下記のコードが追加されます。

public function getType()
{
// TODO: write logic here
}

// TODO: write logic herereturn 'node';に書き換えます。

public function getType()
{
return 'node';
}

もう一度./vendor/bin/phpspec runすると:

通りました!こんな感じでPHPSpecでモデルやモジュールをデザインしながらコーディングすれば,より信頼性の高いコードが書けるようになります