バグ解消法、お役立ち情報など

CakePHPでコントローラーのテストコードを実装する

CakePHP logo

前回はモデルのテストコードについてお伝えしました。

CakePHPでデータベースのテストコードを実装する

今回は、コントローラーのテストです。

注意点として、コントローラーのテストは「単体テスト」ではなく「統合テスト」と呼ばれており、あまりボリュームを増やさない方がよいとされています。

テストのピラミッドを3分で理解する

基本的に公式ドキュメントに沿っていますので、よければご参照ください。

テスト - 3.10

CakePHPのバージョンは3を想定しています。

他のバージョンをお使いの場合は、適宜読み替えて下さい。

実装例

では、以下のCompaniesControllerのアクションメソッドをテストしてみたいと思います。

実メソッド

CompaniesController.php
class CompaniesController extends AppController { public function details($companyId = null) { // 略 } }

detailsというアクションがあります。

引数で$companyIdを受け取り、ビューをレンダリングします。

(記述をシンプルにするため、useなどは省略しています)

このアクションをテストしてみましょう!

テストクラス

テストクラスの作成は、以下のbakeコマンドで行います。

bin/cake bake test Controller <table>

今回のCompanyテーブルの場合、以下のコマンドになります。

bin/cake bake test Controller Companies

すると、以下のようなテストクラスが自動で作成されます。

path/to/tests/TestCase/Controller/CompaniesControllerTest.php
<?php namespace App\Test\TestCase\Controller; use Cake\TestSuite\IntegrationTestTrait; use Cake\TestSuite\TestCase; class CompaniesControllerTest extends TestCase { use IntegrationTestTrait; }

では、detailsアクションのテストを書いてみましょう。

path/to/tests/TestCase/Controller/CompaniesControllerTest.php
<?php namespace App\Test\TestCase\Controller; use Cake\TestSuite\IntegrationTestTrait; use Cake\TestSuite\TestCase; class CompaniesControllerTest extends TestCase { use IntegrationTestTrait; public function testDetails() { $this->get('/companies/details/1'); $this->assertResponseOk(); } }

テストの内容は以下のとおりです。

CompaniesControllerの'details'アクションにid=1のパラメータを渡してアクセスすると、200レスポンスが返ってくること

アサート関連メソッドは色々な種類がありますので、よければPHPUnitの公式ドキュメントもご参照ください!

1. Assertions — PHPUnit 10.1 Manual

もしdetailsアクション内でデータベースのアクセスが存在する場合は、Fixtureを使うことでテストが可能です。

詳細は前回の記事、または公式ドキュメントをご参照ください。

フィクスチャーの作成

また、ありがちなパターンとして「テスト内のアクセスが認証されておらず、ログインページへリダイレクトされてしまう」ことがあります。

そんな時は、認証情報を準備してあげましょう。

今回は、setUpメソッド内でセッションに値を入れてやることで、認証を通します。

path/to/tests/TestCase/Controller/CompaniesControllerTest.php
<?php namespace App\Test\TestCase\Controller; use Cake\TestSuite\IntegrationTestTrait; use Cake\TestSuite\TestCase; class CompaniesControllerTest extends TestCase { use IntegrationTestTrait; // ← このクラスが必要 public function setUp() { parent::setUp(); $this->session([ 'Auth' => [ 'id' => 'xxx', // 認証に必要な値を指定する ], ]); } public function testDetails() { $this->get('/companies/details/1'); $this->assertResponseOk(); } }

セッションにどんな情報が必要かわからない場合は、デバッグキットをご活躍ください!

https://images-for-yajima-tech-blog.s3.amazonaws.com/スクリーンショット 2023-05-19 19.24.35.png

では、いよいよテストを実行してみましょう!

テスト実行

以下のコマンドでテストを実行します。

vendor/bin/phpunit

テストが成功すると、以下のような表示になります!

お疲れ様でした。

終わりに

コントローラーのテストを書くようになってから、実装スピードが格段に上がったと感じます。

ページ数が多くなるにつれ、「ブラウザから久しぶりにアクセスしたらエラーになっている」ということがよくあり、常に不安を抱えながら開発していました。

今回のようなテストがあれば、少なくともエラーにはなっていない(= ページはちゃんと表示できる!)ということを確認できるので、精神衛生上とても助かっています。

テストを書くことで、心置きなく開発に集中できるようになりました!

みなさまもぜひ、コントローラーのテストを取り入れてみてはいかがでしょうか。

それでは。

バグ解消法、お役立ち情報など