CodeIgniter1.7.2でSimpleTestを動かせました!
phpフレームワーク勉強会で作っているショッピングカートなのですが、
機能追加していくうちに、あるモデルクラスが大きくなってきたので、2つに分けようと考えています。
分割してコードが整理できるのはいいのですが、その結果、バグが生まれてしまっては本末転倒なので、
良い機会なので、ちゃんとテストを書こうと思い立ちました。
CodeIgniterには、ユニットテストクラスがあるのですが、いろいろ工夫しないと、
テストしたいコードの中に直書きになってしまうので、
PHPUnitとか、SimpleTestを使ってみたかったのですが、簡単にCodeIgniterに組み込めません。。。
始めは、CIUnit(PHPUnitをCodeIgniterで使えるようにするライブラリ http://www.knollet.com/foostack/)が
CodeIgniter1.7.2に対応していることで使おうとしていたのですが、どうもうまく動かず...
※http://groups.google.co.jp/group/php-beginner/web/ciunit に途中までの記録を残してあります。
そこで、SimpleTestを動かそうと
SimpleTester(http://codeigniter.com/wiki/SimpleTester_-_Unit_testing_library/)
を使おうとしてみたのですが、これもうまくいかず...画面真っ白
最終的に、CodeIgniter Wikiの
http://codeigniter.com/forums/viewthread/63602/
に書いてある方法がうまくいったので備忘録として書いておきます。
1. test用ディレクトリの作成
system/application/
以下にtestというディレクトリを作ります。
2. SimpleTest(http://www.simpletest.org/)とCodeIgniterをつなぐヘルパーを作る
system/application/test/
の下に、
test_helper.php
という名前で作ります。
※SimpleTestはダウンロードして、phpのinclude_pathの通っているところに配置して下さい。
<?php require_once 'simpletest/unit_tester.php'; require_once 'simpletest/reporter.php'; class TestHelper extends UnitTestCase { protected $CI; public function setUp() { $this->CI =& get_instance(); } }
3. コントローラクラスを継承したクラスを作る
system/application/controllers/
の下に、intranet.php
という名前で作ります。
<?php class Intranet extends Controller { public function Intranet() { parent::Controller(); } }
4. testコントローラを作ります
system/application/controllers/
の下に、
test.php
という名前で作ります。
<?php require_once 'intranet.php'; class Test extends Intranet { protected $sTestDirectory; protected $oTestSuite; function Test() { parent::Intranet(); $this->sTestDirectory = dirname(__FILE__).'/../test/'; require_once $this->sTestDirectory . 'test_helper.php'; $this->oTestSuite = new TestSuite(); } function index() { // 全テスト実行 $this->all_tests(); } function all_tests() { // テストコード $this->oTestSuite->addTestFile($this->sTestDirectory . 'models/shop_model.php'); // テスト実行 $this->run(); } protected function run() { $this->oTestSuite->run(new HtmlReporter()); } }
このIntranetクラスがあることで、TestクラスがCodeIgniterの決まり
(Controllerクラスを継承して、http://domain_name/index.php/コントローラ名でアクセスする)
を守りつつ、SimpleTestのクラスもロードできるようにする仕組みを提供しているという感じでしょうか(?)
5. テストコードを書く
/system/application/test/
の下に、
models
というディレクトリを作り、その下に、
shop_modelTest.php
という名前でテストコードを作ります。ここでの名前は慣例的に
テストしたいクラス + Test
としていますが、何でもいいみたいです。
system/application/models/shop_model.php
のテストをしてみます。
詳細は省略してますが、shop_model.phpは、このような内容だとします。
<?php class Shop_model extends Model { function Shop_model() { parent::Model(); } function get_item_list() { return 100; } }
shop_modelTest.phpは、
<?php class Shop_ModelTest extends TestHelper { public function setUp() { parent::setUp(); $this->CI->load->model('Shop_model', 'remote'); } // Shop_modelクラスにあるget_item_list()メソッドのテスト public function test_get_item_list() { // 結果を取得 $aResult = $this->CI->remote->get_item_list(); // 結果は100のはず... $this->assertEqual(100, $aResult); } // 以下、どんどんテストを書きます! }
のように書いておきます。
ここまでできたら、
http://CodeIgniterが動いているドメイン名/test
とアクセスしてみます。
http://CodeIgniterが動いているドメイン名/index.php/test
のようにアクセスします。
すると、
のような画面が出て、テストがうまくいっていることが分かります!
ちなみに、
<?php public function test_get_item_list() { // 結果を取得 $aResult = $this->CI->remote->get_item_list(); // 結果は100のはずだけど、わざと失敗させてみる $this->assertEqual(10, $aResult); }
のような画面が出て、ちゃんと(?)テストが失敗することが確認できます。
ということで、ひとまず導入はできたので、これからテストをばりばり書いて行きたいと思います!!