PhalconアプリケーションをCodeceptionでテストしてみた
先日、Codeceptionが1.8にバージョンアップされました。
1.8での変更点の詳細は本家サイトを見ていただくとして、注目すべきは以下の2点。
- Phalcon Framework の正式サポート
- Environments という概念の追加
1つ目は説明不要と思いますが、2つ目は前回のエントリ (Codeception + Selenium2) Acceptance Testに複数種類のブラウザを利用する - think it over の最後に書いた、以下の課題に対する解決策となっています。
複数種類のブラウザを利用してAcceptance Testを実行したい場合、現状では一つのSuitesにつき一種類のブラウザしか指定ができないため、複数Suitesを用意するしかないようです。
前回からの続きで言うと2つ目を取り上げるべきなのでしょうが、Phalconが楽しそうなので先にそちらを。
0. 前提
1. Phalconアプリケーションの準備
1.2. DBの初期化
$ echo 'CREATE DATABASE invo' | mysql -u root -p $ cat schemas/invo.sql | mysql -u root -p invo
1.3. DB接続設定の変更
app/config/config.ini
の以下の箇所を適切な接続設定となるよう編集します。
[database] host = localhost username = root password = secret name = invo
1.4. 基底URLの変更
ビルトインサーバーで動作確認をしたいので、
app/config/config.ini
の applicationセクションのbaseUrlを以下のように変更します。
[application] (中略) baseUri = /
1.5. ビルトインサーバー用のルーターファイルを作成
Using PHP Built-in webserver — Phalcon 1.2.4 documentation を参考に、invo直下に以下の内容で.htrouter.php
を作成します。
<?php if (!file_exists(__DIR__ . '/' . $_SERVER['REQUEST_URI'])) { $_GET['_url'] = $_SERVER['REQUEST_URI']; } return false;
1.6. 動作確認
以下のコマンドでビルトインサーバーを起動します。
$ php -S localhost:8000 -t ./public .htrouter.php
ブラウザから http://localhost:8000
にアクセスし、次のような画面が表示されることを確認します。
2. Codeceptionの準備
2.1. インストール・初期化
Composerは時間かかるので、今回はpharを使います。
$ curl -L -O http://codeception.com/codecept.phar
ダウンロードできたら、初期化します。
$ php codecept.phar bootstrap
2.2. DB接続設定
本来であればテスト用DBを別で用意したいところですが、PhalconにはSymfonyで言うところの「env」の概念が備わってなくようなので、今回は上で用意したDBを使います。
modules: config: Db: dsn: 'mysql:host=localhost;dbname=invo' user: 'root' password: 'your password' dump: schemas/invo.sql
dump
にはテストデータ投入用のSQLを指定するのですが、invoに同梱されていたものにテストデータが入っているのでそれを使っちゃいましょう。
2.3. Functionalテスト設定の変更
tests/functional.suite.yml
を以下のように編集します。
class_name: TestGuy modules: enabled: [Filesystem, TestHelper, Phalcon1, Db] config: Phalcon1: bootstrap: tests/phalcon_bootstrap.php cleanup: true savepoints: true
編集後、Guyをビルドします。
$ php codecept.phar build
2.4. CodeceptionがPhalconをテストするためのbootstrapファイルを作成
Phalcon1 Module - Codeception - Documentation にもbootstrapファイルに関する記述がありますが、そんな単純ではなかったです。
ちょっと悩みましたが、以下のようにするのが良いとわかりました。
public/index.php
を tests/phalcon_bootstrap.php
にコピーし、以下の変更を行います。
82行目付近
voltテンプレートのキャッシュの保存ディレクトリのパスを以下のように変更します。
"compiledPath" => "../cache/volt/"
↓
"compiledPath" => "./cache/volt/"
141行目付近
Phalcon1 Module - Codeception - Documentation によると、
The application bootstrap file must return Application object but not call its handle() method.
だそうなので、以下のように変更します。
echo $application->handle()->getContent();
↓
return $application;
これでPhalcon, Codeception共に準備完了です。
3. トップページをテストしてみる
以下のコマンドでテストを作成します。
$ php codecept.phar generate:cept functional IndexController/indexAction
作成された tests/functional/IndexController/indexActionCept.php
を以下のように編集します。
<?php $I = new TestGuy($scenario); $I->wantTo('test top page'); $I->amOnPage('/'); $I->see('Welcome to INVO', 'h1');
実行します。
$ php codecept.phar generate:cept run functional -d Codeception PHP Testing Framework v1.8.0.1 Powered by PHPUnit 3.7.28 by Sebastian Bergmann. Functional Tests (1) ----------------------------------------------- Modules: Filesystem, TestHelper, Phalcon1 -------------------------------------------------------------------- Trying to test top (IndexController\indexActionCept.php) Scenario: * I am on page "/" [Response] 200 [Page] http://localhost/ * I see "Welcome to INVO","h1" PASSED -------------------------------------------------------------------- Time: 558 ms, Memory: 7.50Mb OK (1 test, 1 assertion)
無事成功しました。
4. 登録フォームをテストしてみる
以下のコマンドでテストを作成します。
$ php codecept.phar generate:cept functional SessionController/registerAction
作成された tests/functional/SessionController/registerActionCept.php
を以下のように編集します。
<?php $I = new TestGuy($scenario); $I->wantTo('test registration form'); $I->amOnPage('/session/register'); $I->fillField('Your Full Name', 'Phalcon Codeception'); $I->fillField('Username', 'phalcon_codeception'); $I->fillField('Email Address', 'demo@example.com'); $I->fillField('Password', 'demo'); $I->fillField('Repeat Password', 'demo'); $I->click("Register"); $I->seeCurrentUrlEquals('/session/register'); $I->seeRecord('Users', ['name' => 'Phalcon Codeception']);
実行します。
$ php codecept.phar run functional SessionController Codeception PHP Testing Framework v1.8.0.1 Powered by PHPUnit 3.7.28 by Sebastian Bergmann. Functional Tests (1) ------------------------------------------------- Trying to test registration form (\registerActionCept.php) Scenario: * I am on page "/session/register" * I fill field "Your Full Name","Phalcon Codeception" * I fill field "Username","phalcon_codeception" * I fill field "Email Address","demo@example.com" * I fill field "Password","demo" * I fill field "Repeat Password","demo" * I click "Register" * I see current url equals "/session/register" * I see record "Users",{"name":"Phalcon Codeception"} PASSED ---------------------------------------------------------------------- Time: 1.23 seconds, Memory: 8.25Mb OK (1 test, 1 assertion)
問題なくテストにパスしました。