CakePHPでTDDしてみる
どうも、最近、お布団から全然出れないよしかわです。
今回は CakePHP でテスト駆動開発(以下 TDD と称する)をした体験談をまとめていきます。
TDD をすると、どんなメリット、デメリットがあるかに言及していきます。
対象読者
- TDD を知らない人
- CakePHP を業務で触っている人
- 研究で TDD を取り入れたい人
TDD とは
テスト駆動開発(Test-Driven Development)とは、プログラム開発手法の一種で、プログラムに必要な各機能について、最初にテストを書き、そのテストが動作する必要最低限な実装をとりあえず行った後、コードを洗練させる、という短い工程を繰り返すスタイルである。(Wiki 引用)
Clean code that works. 「動作するきれいなコード」。Ron Jeffries の言葉が、TDD の目標です。
TDD はシンプルな 2 つのルールです。
- 自動化されたテストが失敗したときのみ、新しいコードを書く。
- 重複を除去する。
以下がTDDのプロセスです。
- テストを書く(テストファースト)
- 実行して失敗させる
- テストが通る実装を書く
- テストを成功させる
- テストが通る状態のままコードをきれいにする
- 実装を完成させる
TDD の流れ
TDD のサイクルについて紹介します。
- レッド:動作しないテストを 1 つ書く。
- グリーン:そのテストを迅速に動作させる。このステップでは罪を犯してもよい。
- リファクタリング:テストを通すために発生した重複をすべて除去する。
メリット
- バグが少なくなる
- デバッグの時間が短くなる
- コードを書くことで具体化できる
- きれいなコードを作成できる
デメリット
- 実践するのに時間がかかる
- コーディング時間が伸びる
- テストするのが難しいケースがある
- テストコードの保守が必要
インストールする
CakePHP では PHPUnit を導入することができます。
Composer で簡単に導入してみましょう。
php composer.phar require --dev phpunit/phpunit:"^5.7|^6.0"
テストで使用する DB の設定をします。
config/app.php の以下の test の部分を変更します。
'test' => [ 'className' => 'Cake\Database\Connection', 'driver' => 'Cake\Database\Driver\Mysql', 'persistent' => false, 'host' => 'dbhost', 'username' => 'dbuser', 'password' => 'password', 'database' => 'test_database' ],
CakePHP でテストコードを自動生成
多くのフレームワークはテストコードを自動生成してくれます。
ここでは、CakePHP の bake コマンドで自動生成してみましょう。
bin/cake bake test Controller User
bake コマンドで「/tests/TestCase/Controller/UsersControllerTest.php」が生成されました。
テストしてみる
テストの実行は以下のコマンドを入力します。
vendor/bin/phpunit
まずは何も書かずに実行しましょう。
vendor/bin/phpunit PHPUnit 6.5.13 by Sebastian Bergmann and contributors. .IIIII....IIIIIII. 18 / 18 (100%) Time: 506 ms, Memory: 15.25MB OK, but incomplete, skipped, or risky tests! Tests: 18, Assertions: 24, Incomplete: 12.
tests/TestCase 下のテストコードが実行されます。
失敗から成功に
最初にテストコードを書きましょう。
今回満たす要件は以下の 3 つのことです。
- ユーザーについて確認するときに、セッションが確立されていないとリダイレクトする
- ユーザーの追加ができる
- セッション確立後はユーザーの編集が可能である
tests/TestCase/Controller/UsersControllerTest.php
テストを通すために、ログイン機構が必要であるため、以下のようなコードになります。
src/Controller/UsersController.php
リファクタリングをすることがなかったので、本当のTDDにはなっていないですね…
レッドからグリーンにするために、コーディングしていきましょう。
その後から、きれいなコードにしていきます。
まとめ
TDD をしたくなりましたか?
最初からきれいで動作するコードを書くのは、とてもむずかしいですよね。
僕は CircleCI を用いた TDD をしています。やっぱり研究でも役に立つ TDD は良いですね。
ここまで読んでいただき、ありがとうございました!