CodeIgniter: ユニットテストを書いてみる

CodeIgniterでユニットテストはどうするのか?読んだところ、ユニットテストクラスがあるようです。
http://codeigniter.jp/user_guide_ja/libraries/unit_testing.html

ただ、このテストクラスを動かすには、CI_Controller経由で動かすのが普通なのでしょうか。どうもブラウザからテストを起動するURLにアクセスしてテストするという感じっぽいですね。めんどいですね…。まぁほかの方法があるのかもしれませんが、とりあえずやってみます。

ひとまずモデルのテストを書いてみたかったので、それについて書きます。

  1. phpMyAdminでテスト用のデータベースを作成します。hoge_testとかでいいでしょう。
  2. その後、config/database.phpにテスト用データベース情報を定義します。$db[“default”]をコピーして、$db[“test”]を作成し、接続情報を変更しましょう。
  3. $active_groupを一旦、testにしましょう。マイグレーションを走らせるためです。マイグレーションを走らせたらdefaultに戻します。
  4. ここまでで、テスト用のデータベースの準備が整いました。
  5. 次に、テストケースを走らせるためのコントローラーを作成していきます。controller/testsフォルダを作成します。(実際は適当に。)
  6. testsフォルダの下に、testhoge.phpを作成し、Testhogeクラスを作ります。
    <?php
    class Testhoge extends CI_Controller{
    
      function __construct() {
        parent::__construct();
        $this->load->database('test');
        $this->db->trans_start(true);
        $this->load->model('Hoge');
        $this->load->library('unit_test');
        $this->unit->use_strict(true);
      }
    
      function index() {
        $this->test_hoge_insert();
        echo $this->unit->report();
      }
    
      function test_hoge_insert() {
        $id = $this->Hoge->insert("tests", "tests", 12345);
        $this->unit->run($id, 'is_numeric', "hogeを追加後にIDが返ってくること");
      }
    }
    
  7. では、コンストラクタから見ていきます。
      function __construct() {
        parent::__construct();
        $this->load->database('test');
        $this->db->trans_start(true);
        $this->load->model('Hoge');
        $this->load->library('unit_test');
        $this->unit->use_strict(true);
      }
    

    $this->load->database(‘test’)の引数’test’で、データベースに接続するグループを指定しています。これでテスト用のデータベースに接続しました。
    次に、$this->db->trans_start(true)を行っています。これは、トランザクションをテストモードで動かすための設定です。テストを行うたびにDBにデータが蓄積されてしまうので、不要なデータがたまらないように、どんな結果になろうともロールバックさせるために書いてます。
    CodeIgniterのユニットテストは、setUp, tearDownのような前処理・後処理を書くところがありません。やろうと思ったら全部自前で実装しないといけないのだと思います。1つずつテストをしたいときとか、ものすごく面倒ですねぇ…。まぁやる方法を思い浮かぶっちゃ浮かぶけど…。
    話がそれたので、続きを解説します。

  8. 次に、$this->load->model(‘Hoge’)でhogeテーブル用のモデルを読み込んでいます。そして、$this-load->library(‘unit_test’)でユニットテスト用のクラスを読み込んでいます。その後、型の検証を厳密するために、ユニットテストをstrictモードにしています。
  9. 次に、indexをみましょう。
      function index() {
        $this->test_hoge_insert();
        echo $this->unit->report();
      }
    

    $this->test_hoge_insert()で、ユニットテストを実行しています。test_hoge_insertメソッドは後で定義しています。そして、結果をecho $this->unit->report()で出力しています。やっていることはすごくシンプルで、あとはテストの数だけメソッドを追記するか、うまいことメタプログラミングでテストを実行させるか…っていうところです。

  10. 最後にテスト内容です。
      function test_hoge_insert() {
        $id = $this->Hoge->insert("tests", "tests", 12345);
        $this->unit->run($id, 'is_numeric', "hogeを追加後にIDが返ってくること");
      }
    

    $this->Hoge->insertは私が作ったHogeモデルでデータを投入しているだけです。戻り値はidで、失敗したらfalseが返ります。ちゃんと$idに整数が入っているかを確認します。
    $this->unit->run($id, ‘is_numeric’, ‘hogeを追加後にIDが返ってくること’)
    ですが、第1引数に検証対象、第2引数に検証ルール、第3引数に検証タイトルを記述します。

  11. この状態でhttp://localhost/tests/testhoge/にアクセスしたら、テストが実行されます。
  12. 結果は成功して、整数が戻っていました。そして、データベースにも挿入されたテストデータは残っていませんでした。

CodeIgniterのユニットテストは軽く始めてみるにはよさげな感じだけど、ドキュメントが、テストの始め方についての記述がちょっと不親切かなーという印象です。
setUpとtearDownについてはフックメソッドをうまく使えばできると思うので、改良の余地は十分にありますが、最初から準備しておいてほしいなぁという感じがしますね。うーん、でもデフォルトでコマンドラインでできるほうが助かるかな…。


タグ CodeIgniter, PHP | パーマリンク.

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です