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ファイルに

1
2
3
4
5
{
  "require-dev": {
      "benconstable/phpspec-laravel": "~2.0@dev"
  }
}

を追記します。 phpspec.yml

1
2
3
4
extensions:
  - PhpSpec\Laravel\Extension\LaravelExtension
laravel_extension:
  migrate_db: true

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

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

PHPSpecを書いてみる

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

1
php artisan make:model Node

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

1
./vendor/bin/phpspec describe App/Node

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

1
2
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;

1
use PhpSpec\Laravel\EloquentModelBehavior;

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

1
class NodeSpec extends EloquentModelBehavior

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

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

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

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

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

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

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

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

1
2
3
4
public function getType()
{
  // TODO: write logic here
}

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

1
2
3
4
public function getType()
{
  return 'node';
}

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

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