LoginSignup
12
13

More than 5 years have passed since last update.

Laravel5.1でbehatを使ってみる

Last updated at Posted at 2015-07-12

なぜbehatを使うのか

PHPカンファレンス福岡でphpspecとbehatのお話を聞いて
behatのほうがちょっと効率よさそうと感じたので先にbethatのほうをやってみることにしました。

↓その時のスライド
phpspecで始めるBDD
http://www.slideshare.net/yuukitakezawa/phpspec-bdd

behatエクステンションの作り方
http://www.slideshare.net/RyoTomidokoro/behat-49897353

ちなみに私は今までほとんどテストコードを書いたことがない… :fearful:
ずっと「テストコードかかなきゃなぁ」と思いながら従来のアナログな方法でやっていたわけです。ダメ人間ですね。

環境

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

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って表示されている」
を書いてみる。

features/home.feature
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を書き足す。

features/bootstrap/FeatureContext.php
<?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)

12
13
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
13