OthloBlog - オスロブログ -

名古屋のIT系学生コミュニティOthloTechのブログです。

CakePHPでTDDしてみる

どうも、最近、お布団から全然出れないよしかわです。

今回は CakePHP でテスト駆動開発(以下 TDD と称する)をした体験談をまとめていきます。

TDD をすると、どんなメリット、デメリットがあるかに言及していきます。

対象読者

  • TDD を知らない人
  • CakePHP を業務で触っている人
  • 研究で TDD を取り入れたい人

TDD とは

テスト駆動開発(Test-Driven Development)とは、プログラム開発手法の一種で、プログラムに必要な各機能について、最初にテストを書き、そのテストが動作する必要最低限な実装をとりあえず行った後、コードを洗練させる、という短い工程を繰り返すスタイルである。(Wiki 引用

Clean code that works. 「動作するきれいなコード」。Ron Jeffries の言葉が、TDD の目標です。

TDD はシンプルな 2 つのルールです。

  • 自動化されたテストが失敗したときのみ、新しいコードを書く。
  • 重複を除去する。

以下がTDDのプロセスです。

  1. テストを書く(テストファースト)
  2. 実行して失敗させる
  3. テストが通る実装を書く
  4. テストを成功させる
  5. テストが通る状態のままコードをきれいにする
  6. 実装を完成させる

TDD の流れ

TDD のサイクルについて紹介します。

  • レッド:動作しないテストを 1 つ書く。
  • グリーン:そのテストを迅速に動作させる。このステップでは罪を犯してもよい。
  • リファクタリング:テストを通すために発生した重複をすべて除去する。

f:id:yoshikawataiki:20181031223344p:plain

メリット

  • バグが少なくなる
  • デバッグの時間が短くなる
  • コードを書くことで具体化できる
  • きれいなコードを作成できる

デメリット

  • 実践するのに時間がかかる
  • コーディング時間が伸びる
  • テストするのが難しいケースがある
  • テストコードの保守が必要

インストールする

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 は良いですね。

ここまで読んでいただき、ありがとうございました!

参考文献

テスト駆動開発

テスト駆動開発(TDD)

バグは早めに潰す!テスト駆動開発(TDD)の概要とメリット・デメリット

CakePHP test - 3.6