読者です 読者をやめる 読者になる 読者になる

Today Fortkle Learned.

知らないことの方が多いので今更調べています。さらに一歩先に行けたら嬉しいです。

PHPアプリケーションをRspecでテストする

php

この投稿はPHP Advent Calendar 2014の4日目の記事です。

Webブラウザを操作して実施するテスト(以降ブラウザテストと表記)をPHPアプリケーションで実施したい思ってPHP製のテストフレームワークを探していたのですが、あまりよいものが見つからず日本語の情報も少なかったので、いっそのことRspec+Capybaraでやってしまえ!ということでやってみました。

目次

  1. 概要
  2. 用語の説明
  3. PHPアプリケーションをRspec+Capybaraでテストする
  4. テストをTravisCIで実行する

1. 概要

簡単いうと、PHPアプリケーションをビルドインサーバーで動かし、その環境に対してRspecとCapybaraで書かれたテストケースを実行することでブラウザテストを行います。

環境はCentOS release 6.6 (Final)、PHP 5.5.19で実行しています。PHPのバージョンはビルドインサーバーが使える5.4以上であればOKです。
rspecは諸事情により2系。3系の場合はrspec-legacy_formattersというgemが必要になります。詳しくはこちら)。

使っている技術キーワードとしては、 Rspec + Capybara + PhantomJS(Poltergeist) という感じです。

2. 用語の説明

いきなりRspec + Capybara + PhantomJS(Poltergeist)といっても何がどんなことをしているのか分からないと思うので、それぞれの用語に対して簡単に説明します。

  • Rspec
  • Capybara
    • テストフレームワークに対して、Webアプリのテストを書きやすくする語彙を提供してくれるヘルパー。
    • click_onやfill_inといった指示が使える。(詳しくはcapybaraのREADME参照。)
    • これによってRspecでブラウザテスト(結合テスト)がやりやすくなる。
  • PhantomJS
    • ヘッドレス(ブラウザの起動無しにJSが実行できる)ブラウザ。
    • Capybaraのデフォルトの実行ドライバはRackTestだが、Javascriptの実行はサポートされていないためPhantomJSだと幸せになれる。
    • JSが実行できるドライバにSeleniumがあるが、毎回実際のブラウザが起動するのでヘッドレスなPhantomJSだと幸せになれる。
  • Poltergeist
    • CapybaraでPhantomJSを使うためのライブラリ。

3. PHPアプリケーションをRspec+Capybaraでテストする

それではさっそくブラウザテストが実行できる環境を作っていきましょう。必要なツール類をインストールしていくところから始めていきます。

PhantomJS のインストール

まずはPhantomJSをインストールします。 環境がUbuntuではなくCentOSですが、下記記事を参考にインストールできました。

UbuntuにPhantomJS入れた - Qiita

rbenv + ruby-build のインストール

続いて、Rspec, Capybara, Poltergeistのインストールですが、これらはRubyGemsで配布されています。 rubyを使うことになるので、まずは rbenv + ruby-build でrubyの環境を作りましょう。 インストールは下記記事を参考に行いました。

rbenv を使って ruby をインストールする(CentOS編) - Qiita

rubyのバージョンはgemが使えば何でもいいですが、今回は2.1.5にしました。 下記のようにバージョンを確認できればOKです。

※僕の環境だとopenssl-develが必要でした。
$ sudo yum install openssl-devel

$ ruby -v
ruby 2.1.5p273 (2014-11-13 revision 48405) [x86_64-linux]

続いてgem管理のためにグローバルにbundlerをインストールしましょう。

$ gem install bundler
$ rbenv rehash
// 確認
$ bundle -v
Bundler version 1.7.7

Rspec, Capybara, Poltergeist のインストール

やっとRspec, Capybara, Poltergeist のインストールです。 今回はLaravelで作られたアプリケーションにテスト環境を作っていきます。 リポジトリルートにGemfileを作りましょう。

$ cd [リポジトリのルートディレクトリ]
$ vim Gemfile

下記内容でGemfileを保存します。

source 'https://rubygems.org'
                                                                                                                                                              
gem 'rspec' , '<= 2.14.1'
gem 'capybara-mechanize'
gem 'poltergeist'

続いてGemのインストール。ローカルにインストールしたいのでpathを指定します。

※僕の環境だと色々必要でした。

// bundle install できない(nokogiriが入らない)
$ sudo yum install libxml2-devel libxslt-devel
$ gem install nokogiri -- --use-system-libraries=true --with-xml2-include=/usr/include/libxml2/
$ bundle config build.nokogiri --use-system-libraries

// bundle install できない(unf_extが入らない)
$ sudo yum install gcc-c++
// インストール
$ bundle install --path vendor/bundle
〜略〜
Your bundle is complete!
It was installed into ./vendor/bundle
// 確認
$ bundle exec gem list

*** LOCAL GEMS ***

bundler (1.7.7)
capybara (2.4.4)
capybara-mechanize (1.4.0)
cliver (0.3.2)
diff-lcs (1.2.5)
domain_name (0.5.22)
http-cookie (1.0.2)
mechanize (2.7.3)
mime-types (2.4.3)
mini_portile (0.6.1)
multi_json (1.10.1)
net-http-digest_auth (1.4)
net-http-persistent (2.9.4)
nokogiri (1.6.5)
ntlm-http (0.1.1)
poltergeist (1.5.1)
rack (1.5.2)
rack-test (0.6.2)
rspec (2.14.1)
rspec-core (2.14.8)
rspec-expectations (2.14.5)
rspec-mocks (2.14.6)
unf (0.1.4)
unf_ext (0.0.6)
webrobots (0.1.1)
websocket-driver (0.4.0)
xpath (2.0.0)

テストを実行してみる

とりあえずとても簡単なテストを動かしてみるところまでやってみます。 ビルドインサーバーでテスト対象のアプリケーションを動かしましょう。

// ビルドインサーバーの起動
$ php -S localhost:3000
// Laravelなら
php artisan serve --port 3000

次にテストケースを作っていきます。

// テストケースをまとめるディレクトリを作ります
$ cd [リポジトリのルートディレクトリ]
$ mkdir spec
// rspecのヘルパーを作ります
$ vim spec/spec_helper.rb

下記内容でspec_helper.rbを保存します。

#!/bin/env ruby
# encoding: utf-8
require 'capybara/rspec'
require 'capybara/poltergeist'

module ::RSpec::Core
    class ExampleGroup
        include Capybara::DSL 
    end
end

# アプリケーション設定
Capybara.app = "アプリケーション名"
Capybara.javascript_driver = :poltergeist
// テスト対象の環境を指定する。先ほど起動したビルドインサーバーの環境を指定。
Capybara.app_host = 'http://localhost:3000'
Capybara.run_server = false
Capybara.register_driver :poltergeist do |app|
    Capybara::Poltergeist::Driver.new(app, :js_errors => false, :timeout => 60)
end

アプリケーションのルート(/)にアクセスした際のHTTPステータスコードが200であることを 確認するテストを書いてみます。
spec/ディレクトリの配下にindex_spec.rbを作成し、下記の内容で保存します。

#!/bin/env ruby
# encoding: utf-8

require File.dirname(__FILE__)+'/spec_helper'

describe 'トップページ' do
    describe 'スモークテスト', :js => true do
        context 'トップページにアクセスした時' do
            it 'HTTPステータスが200であること' do
                visit "/"
                expect(page.status_code).to eq(200)
            end
        end
    end
end

ではrspecを実行してみましょう!

// rspecの実行はルートで行う
$ cd [リポジトリのルートディレクトリ]
$ bundle exec rspec spec/index_spec.rb 
.

Finished in 1.56 seconds
1 example, 0 failures

おめでとうございます!
テストが1件実行され、GREEN(OK)だったことが確認できました!

他にどのようなテストケースが書けるかは、CapybaraのREADMEを見てチェックしてください!
また、僕のリポジトリでも実際にいくつかテストケースを書いているので興味があれば参考にしてみてください。

4. テストをTravisCIで実行する

最後に作成したテストをTravisCI上で実行してみましょう!
TravisCIの設定は割愛させてもらって、既にTravisCIが動いているという前提で .travis.yml を下記のように修正します(アプリケーション固有の設定は別途行って下さい)。

language: php

php:
  - 5.4
  - 5.5

before_install:
  - sudo apt-get install libxslt-dev libxml2-dev
  - export DISPLAY=:99.0
  - sh -e /etc/init.d/xvfb start
  - php -S localhost:3000 -t public/ > /tmp/server.log 2>&1 &

before_script:
  - composer install
  - bundle config build.nokogiri --use-system-libraries
  - bundle install --path vendor/bundle

script:
  - bundle exec rspec spec

以上の記述でTravisCI上でもテストを実行することができました!

おつカレー様でした!

PHPアドベントカレンダーなのにrubyばっかり書いてるとか言わないの