CodeIgniter3でのテスト

CodeIgniter3でのテストについて、資料を作りましたので公開します。

(2020-03-29 追記) 見やすいようにマインドマップを更新し、マップの内容を本文に追記しました。

プレゼン資料

CodeIgniterのアーキテクチャ

CodeIgniterインスタンス

  • get_instance() で取得できるヤツ
  • 神オブジェクト的なシングルトンぽいもの
  • 実体はControllerのインスタンス
    • 想定
    • 1つのリクエストで1つしか生成されない

CI_Loaderクラス

  • モデル、ライブラリなどをロードするもの
  • 生成されたインスタンスをCodeIgniterインスタンスのプロパティに動的に追加する
    • CodeIgniterインスタンスが神オブジェクト化する
    • $this->foo がコントローラ、モデルで同じように使える
  • 関数にも依存している
    • load_class()
    • is_loaded()

CodeIgniter3のテスト上の問題点

グローバル状態

  • シングルトン
    • グローバル変数
  • 関数内のスタティック変数

exit() での終了

クラス名の衝突

  • 複数のコントローラに全く同じクラス名を付けられる

隠れた依存

ci-phpunit-test

ci-phpunit-testとは?

  • CodeIgniter3とPHPUnitをつなぐブリッジツール
  • 基本はPHPUnit
  • CodeIgniter本体のコードの書き換えは一切不要

アーキテクチャ

  • グローバル状態のリセット
    • CodeIgniterインスタンスのリセット
  • 構成
    • オートローダ
    • CodeIgniterのファイルの動的な置き換え
      • テスト上の問題点を解消する
    • $this->request によるControllerの機能テスト
    • ヘルパークラスやメソッド
      • テストコードを書きやすくするためのもの
      • ヘルパークラス
        • ReflectionHelper
      • ヘルパーメソッド
        • $this->getDouble()
    • Monkey Patch
      • ライブラリとして実装されている
      • 自転車の補助輪のようなもの
      • 最後の手段

テスト作成上のテクニック

resetInstance()

  • 何をするか?
    1. CodeIgniterインスタンスをリセットする
    2. 新しいCodeIgniterインスタンスを生成する
    3. $this->CI にCodeIgniterインスタンスを代入する
  • 呼び出し不要
    • newController()/newLibrary()/newModel() を使う場合
    • $this->request を使う場合

依存オブジェクトの注入

  • CI_Loaderにより作成されたプロパティはすべて動的なプロパティ
    • つまりpublic
      • インスタンス化後には外から注入可能
  • Controllerのテストの場合
    • setCallable()/addCallable() でプロパティにモックを注入すればよい

サンプルテストコード

さらに学習するには?

Date: 2017/09/22

Tags: codeigniter, testing, phpunit