なぜbehatを使うのか
PHPカンファレンス福岡でphpspecとbehatのお話を聞いて
behatのほうがちょっと効率よさそうと感じたので先にbethatのほうをやってみることにしました。
↓その時のスライド
phpspecで始めるBDD
http://www.slideshare.net/yuukitakezawa/phpspec-bdd
behatエクステンションの作り方
http://www.slideshare.net/RyoTomidokoro/behat-49897353
ちなみに私は今までほとんどテストコードを書いたことがない…
ずっと「テストコードかかなきゃなぁ」と思いながら従来のアナログな方法でやっていたわけです。ダメ人間ですね。
環境
Laravel5時代のhomesteadをベースとしたオレオレVagrant環境を構築済み。
仮想のUbuntu上で作業します。
使うもの
ぐぐったらそれようのがあったのでこれを使う
https://github.com/laracasts/Behat-Laravel-Extension
設定手順
上記のREADME.mdと動画の手順で進めてみる。
動画
https://laracasts.com/lessons/laravel-5-and-behat-bffs
composerで一式入れる
laravelのディレクトリに移動して以下を実行
sudo composer require behat/behat behat/mink behat/mink-extension laracasts/behat-laravel-extension --dev
behat.ymlを作る
内容もREADMEのをベースにしてenv_pathに.env
を指定
vim behat.yml
default:
extensions:
Laracasts\Behat:
env_path: .env
Behat\MinkExtension:
default_session: laravel
laravel: ~
Laravelの.env
をbehat用に用意したいなら、env_path
はコメントアウトするかファイル指定するといいよ。といってると理解した。
behat --init
venderの中にbehatがあるのでコマンド実行
$ vendor/behat/behat/bin/behat --init
+d features - place your *.feature files here
+d features/bootstrap - place your context classes here
+f features/bootstrap/FeatureContext.php - place your definitions, transformations and hooks here
- featuresディレクトリ作ったよ!featureファイルはここに入れてね!
- その中にbootstrapも作ったよ!
- FeatureContext.phpも雛形作ったよ!あなたの定義はここに書いてね
といった所でしょうか
featureを書く
Laravel5.1を入れたままの状態なのでテストの内容は
「トップページにアクセスしたらLaravel5って表示されている」
を書いてみる。
Feature: show laravel home
Scenario: Home
Given I am on the homepage
Then I should see "Laravel 5"
FeatureContext.php
behatのひな形のままでは動かない、
「Behat\MinkExtension\Context\MinkContextを継承してね。」と書いてあるので読み込んでextendsを書き足す。
<?php
use Behat\Behat\Context\Context;
use Behat\Behat\Context\SnippetAcceptingContext;
use Behat\MinkExtension\Context\MinkContext;
/**
* Defines application features from the specific context.
*/
class FeatureContext extends MinkContext implements Context, SnippetAcceptingContext
{
/**
* Initializes context.
*
* Every scenario gets its own context instance.
* You can also pass arbitrary arguments to the
* context constructor through behat.yml.
*/
public function __construct()
{
}
}
DBへの変更が反映されないようにTransactionを使ったロールバック用traitや
メール送信のテストで送りたくないとき用のtraitも用意されている模様。
使う時はFeatureContextに使いたいtraitで読み込んで使うといいよとのこと。
動かしてみる
$ vendor/behat/behat/bin/behat
Feature: show laravel home
Scenario: Home # features/home.feature:3
Given I am on the homepage # FeatureContext::iAmOnHomepage()
Then I should see "Laravel 5" # FeatureContext::assertPageContainsText()
1 scenario (1 passed)
2 steps (2 passed)
0m1.16s (23.85Mb)
無事テストができた。
書けるテスト一覧
まだ書けるテストを把握しきれていない。
vendor/behat/behat/bin/behat -dl
を実行すると一覧が表示されるので
これを参考にぐぐって模索。
デフォでは以下のテストが書ける。
$ vendor/behat/behat/bin/behat -dl
default | Given /^(?:|I )am on (?:|the )homepage$/
default | When /^(?:|I )go to (?:|the )homepage$/
default | Given /^(?:|I )am on "(?P<page>[^"]+)"$/
default | When /^(?:|I )go to "(?P<page>[^"]+)"$/
default | When /^(?:|I )reload the page$/
default | When /^(?:|I )move backward one page$/
default | When /^(?:|I )move forward one page$/
default | When /^(?:|I )press "(?P<button>(?:[^"]|\\")*)"$/
default | When /^(?:|I )follow "(?P<link>(?:[^"]|\\")*)"$/
default | When /^(?:|I )fill in "(?P<field>(?:[^"]|\\")*)" with "(?P<value>(?:[^"]|\\")*)"$/
default | When /^(?:|I )fill in "(?P<field>(?:[^"]|\\")*)" with:$/
default | When /^(?:|I )fill in "(?P<value>(?:[^"]|\\")*)" for "(?P<field>(?:[^"]|\\")*)"$/
default | When /^(?:|I )fill in the following:$/
default | When /^(?:|I )select "(?P<option>(?:[^"]|\\")*)" from "(?P<select>(?:[^"]|\\")*)"$/
default | When /^(?:|I )additionally select "(?P<option>(?:[^"]|\\")*)" from "(?P<select>(?:[^"]|\\")*)"$/
default | When /^(?:|I )check "(?P<option>(?:[^"]|\\")*)"$/
default | When /^(?:|I )uncheck "(?P<option>(?:[^"]|\\")*)"$/
default | When /^(?:|I )attach the file "(?P<path>[^"]*)" to "(?P<field>(?:[^"]|\\")*)"$/
default | Then /^(?:|I )should be on "(?P<page>[^"]+)"$/
default | Then /^(?:|I )should be on (?:|the )homepage$/
default | Then /^the (?i)url(?-i) should match (?P<pattern>"(?:[^"]|\\")*")$/
default | Then /^the response status code should be (?P<code>\d+)$/
default | Then /^the response status code should not be (?P<code>\d+)$/
default | Then /^(?:|I )should see "(?P<text>(?:[^"]|\\")*)"$/
default | Then /^(?:|I )should not see "(?P<text>(?:[^"]|\\")*)"$/
default | Then /^(?:|I )should see text matching (?P<pattern>"(?:[^"]|\\")*")$/
default | Then /^(?:|I )should not see text matching (?P<pattern>"(?:[^"]|\\")*")$/
default | Then /^the response should contain "(?P<text>(?:[^"]|\\")*)"$/
default | Then /^the response should not contain "(?P<text>(?:[^"]|\\")*)"$/
default | Then /^(?:|I )should see "(?P<text>(?:[^"]|\\")*)" in the "(?P<element>[^"]*)" element$/
default | Then /^(?:|I )should not see "(?P<text>(?:[^"]|\\")*)" in the "(?P<element>[^"]*)" element$/
default | Then /^the "(?P<element>[^"]*)" element should contain "(?P<value>(?:[^"]|\\")*)"$/
default | Then /^the "(?P<element>[^"]*)" element should not contain "(?P<value>(?:[^"]|\\")*)"$/
default | Then /^(?:|I )should see an? "(?P<element>[^"]*)" element$/
default | Then /^(?:|I )should not see an? "(?P<element>[^"]*)" element$/
default | Then /^the "(?P<field>(?:[^"]|\\")*)" field should contain "(?P<value>(?:[^"]|\\")*)"$/
default | Then /^the "(?P<field>(?:[^"]|\\")*)" field should not contain "(?P<value>(?:[^"]|\\")*)"$/
default | Then /^the "(?P<checkbox>(?:[^"]|\\")*)" checkbox should be checked$/
default | Then /^the checkbox "(?P<checkbox>(?:[^"]|\\")*)" (?:is|should be) checked$/
default | Then /^the "(?P<checkbox>(?:[^"]|\\")*)" checkbox should not be checked$/
default | Then /^the checkbox "(?P<checkbox>(?:[^"]|\\")*)" should (?:be unchecked|not be checked)$/
default | Then /^the checkbox "(?P<checkbox>(?:[^"]|\\")*)" is (?:unchecked|not checked)$/
default | Then /^(?:|I )should see (?P<num>\d+) "(?P<element>[^"]*)" elements?$/
default | Then /^print current URL$/
default | Then /^print last response$/
default | Then /^show last response$/
テストに失敗する原因がわからないときは、下の三つを駆使して状況をみることもできる。
default | Then /^print current URL$/
default | Then /^print last response$/
default | Then /^show last response$/
次回は
2015.7.29追記 もっとテスト書いてみた
Behat-Laravel-Extensionを使ってLaravel5のログイン認証をテストする
このテストをこれまで構築していた
GitHubにPushしたら動くようにしたjenkinsさんで、テストが走るように設定をしてみる。
さくらのVPSにjenkinsをインストールして、テストOKで自動デプロイする環境を構築する(1)
さくらのVPSにjenkinsをインストールして、テストOKで自動デプロイする環境を構築する(2)
さくらのVPSにjenkinsをインストールして、テストOKで自動デプロイする環境を構築する(3)
さくらのVPSにjenkinsをインストールして、テストOKで自動デプロイする環境を構築する(4)