JenkinsでCakeBehat
Behat/Minkのテストはブラウザでアクセスされるので、テスト時はtestデータソースを使用するように工夫が必要。
The Opera blog
あと、アクセス先のテスト用DBの初期化、後始末が必要。
も一つ、ciサーバ内で完結するなら、ciサーバ上でのwebサーバ設定が必要。
もしくは、ciサーバ上から別サーバ上にアクセスする場合、git hook時に別サーバ上のソースの更新とDBの(ry
面倒なので、ciサーバで完結できるようにする
実装
ホスト名がtestから始まっていた場合は、testデータソースを使用する。
app/Config/database.php
<?php public function __construct() { $env = env('CAKE_ENV'); if ($this->__isCakeBehatAccess()) { $env = 'test'; } if (property_exists(__CLASS__, $env)) { $this->default = $this->{$env}; } else { $this->default = $this->production; } } private function __isCakeBehatAccess() { $server = isset($_SERVER['SERVER_NAME']) ? $_SERVER['SERVER_NAME'] : ''; if (strpos($server, 'test') === 0) { return true; } return false; }
テスト用DBの初期化、後始末を行う
app/Test/features/bootstrap/FeatureContext.php
<?php /** * @BeforeSuite */ public static function setup($event) { $fmt = '(cd %s && bash ./Console/cake Migrations.migration run all -c test)'; $cmd = sprintf($fmt, APP); exec($cmd); } /** * @AfterSuite */ public static function teardown($event) { $tables = array(); $db = ConnectionManager::getDataSource('test'); $db->cacheSources = false; $usePrefix = empty($db->config['prefix']) ? '' : $db->config['prefix']; if ($usePrefix) { foreach ($db->listSources() as $table) { if (!strncmp($table, $usePrefix, strlen($usePrefix))) { $tables[] = substr($table, strlen($usePrefix)); } } } else { $tables = $db->listSources(); } $fmt = 'DROP TABLE %s;'; foreach ($tables as $t) { $sql = sprintf($fmt, $db->fullTableName($t)); $db->execute($sql); } }
設定とか
app/Config/behat.yaml
default: context: parameters: # TODO base_urlがDRYじゃない base_url: 'http://test.example.com/' extensions: Behat\MinkExtension\Extension: base_url: 'http://test.example.com/' goutte: ~ selenium2: wd_host: "http://localhost:8643/wd/hub"
<?xml version="1.0" encoding="utf-8"?> <project name="project" default="behat"> <target name="behat" depends="init, start_phontomjs, submodule_update, cakebehat, stop_phontomjs"></target> <target name="init" > <delete dir= "./reports" includeemptydirs= "true" /> <mkdir dir= "./reports" /> </target> <target name="submodule_update"> <exec executable="git" > <arg line="submodule update --init --recursive" /> </exec> </target> <target name="cakebehat" depends= "install_behat, change_tmp_permision"> <exec executable="./lib/Cake/Console/cake" > <arg line=" CakeBehat.bdd --config ./app/Config/behat.yml --profile default --format junit --out ./reports/" /> </exec> </target> <target name="change_tmp_permision"> <exec command="find tmp -type d | xargs chmod 0777" dir="./app/" /> </target> <target name="install_behat" depends= "install_composer"> <exec command="php composer.phar install" dir="./app/Plugin/CakeBehat" /> </target> <target name="install_composer"> <exec command="curl http://getcomposer.org/installer | php" dir="./app/Plugin/CakeBehat" /> </target> <target name="start_phontomjs"> <exec command="/usr/local/bin/phantomjs --webdriver=8643 >/dev/null 2>&1 &" /> </target> <target name="stop_phontomjs"> <exec command="killall phantomjs" /> </target> </project>
全体的にかなり力技。もっとスマートなやり方があるんじゃまいか?
他のテストでphantomjsが走ってたら、killallはまずい。。