RSpec Capybara Webkit Xvfb CentOS 要するにRailsでjavascriptをテストしたい
RSpec + Capybara のセットアップは簡単でいいんですが、javascriptのテストができません。
いざ本当にウェブサイトやウェブアプリのテストしようと思ったらjavascriptのテストは必須。
それを可能にするには意外にも長い道のりがあるので、まとめておきます。
想定する開発環境はこんな感じ。
- Vagrant (Virtual box)
CentOS 6.4
ここでつまずいたらドットインストールで学習
ローカル開発環境の構築 (全12回) - プログラミングならドットインストール
Vagrant入門 (全13回) - プログラミングならドットインストールRails4
RSpec
Capybara
テストについてよくわからなければ、このチュートリアルで学習。
Ruby on Rails チュートリアル:実例を使って Rails を学ぼう
テスト駆動開発の定義とは、アプリケーションを開発するときに最初にテストを作成し、次にコードを作成することです。この開発手法に慣れるまでには多少時間がかかるかもしれませんが、一度慣れてしまえば大きなメリットを得られます。失敗するテストを最初に書き、テストにパスするコードを次に実装することで、しかるべき振る舞いがテストによって正しく検証されている、という自信が付きます。
- スタート地点 • Rails4でアプリ書いてて、テストもしてるけど、javascriptを交えたテストはまだしていない。 • Capybaraではjavascriptが動作しないのでテストに失敗する。
道のり
- javascriptのテストには describe に js: true オプションをつければよい
- その際使われるデフォルトの javascript_driver は selenium
javascript_driver を capybara-webkit に変更することもできる
-- CentOS に QT をインストールする必要があるselenium にしろ webkit にしろ、仮想サーバーでテストするのでディスプレイがない( headless )
-- ディスプレイ処理を可能にする X が必要
-- X を仮想的に実現する Xvfb ( virtual framebuffer X server )
-- Xvfb を ruby から簡単に立ち上げられる headless という Gem があるjs: true を付けられたテストは、別スレッドでRailsアプリケーションを起動しテストする
-- そのためデータベースが各テストで共有されず、エラーになる
--- config.use_transactional_fixtures は使わない
--- database_cleaner を使って毎回データベースを掃除するspec_helper.rb をもろもろ変更する
Xvfb
インストール
1
2
3
4
5
6
7
$ yum search Xvfb
===== N/S Matched: Xvfb =====
xorg-x11-server-Xvfb.x86_64 : A X Windows System virtual framebuffer X server.
$ sudo yum groupupdate "X Window System"
$ sudo yum install xorg-x11-server-Xvfb
確認
1
2
3
ディスプレイ番号を環境変数に設定。
$ DISPLAY=:1.0
$ export DISPLAY
Xvfbをディスプレイ番号:1、スクリーン番号:0、幅:1024px、高さ:768px、ビット深度:24bit で起動。
1
2
3
4
5
6
7
8
コマンドの最後に&を付加することにより、バックグラウンドで動かすことができる。
$ Xvfb :1 -screen 0 1024x768x24&
実行中のジョブを表示するには下記.
$ jobs
終了する
$ killall Xvfb
テストとは直接関係ないけど xwd と ImageMagick をインストールしたらスクリーンショットも撮れる。
1
2
3
4
5
6
7
8
9
10
$ yum install ImageMagick
$ yum install xwd
$ xwd -display :1 -root -out test.xwd
-display ディスプレイ番号
-root ディスプレイ全体を撮る
-out 出力ファイル名
ImageMagickのconvertコマンドでpngに変換。
$ convert test.xwd test.png
Gem
必要なGemをインストールする。
1
2
3
4
5
6
7
8
group :test do
gem 'selenium-webdriver', '~> 2.35.1' # javascript_driver
gem 'capybara', :git => 'git://github.com/jnicklas/capybara.git'
gem 'factory_girl_rails', '4.2.1'
gem 'database_cleaner' # データベースが絡むテストには必要
# gem 'capybara-webkit' # デフォルトのjavascript_driverを変更する場合
gem 'headless' # Railsから簡単にXvfbを起動できる
end
capybara-webkitのインストールにはQTが必要。
※ ページ下部を参照。
1
$ bundle install
spec_helper.rb
spec_helper.rbにいろいろ設定する。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
.
.
require 'rspec/rails'
require 'rspec/autorun'
require 'capybara/rspec'
require 'capybara-webkit'
require 'headless'
require 'database_cleaner'
RSpec.configure do |config|
Capybara.javascript_driver = :selenium
# もしくは、Capybara.javascript_driver = :webkit
config.before(:suite) do
# Xvfbを起動するheadlessの設定
Headless.new(:destroy_on_exit => false).start
end
# javascriptテストとスレッドを共有するにはfalseにする
config.use_transactional_fixtures = false
.
.
end
database_cleaner
spec/support/に database_cleaner.rb というファイルを作成
※ ファイル名はお好みで
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
RSpec.configure do |config|
# 処理が高速なので、普段はtransactionを使用する
config.before(:each) do
DatabaseCleaner.strategy = :transaction
end
# jsオプションが有効な時のテストはtruncationを使用
config.before(:each, :js => true) do
DatabaseCleaner.strategy = :truncation
end
# database cleaner の設定
config.before(:suite) do
DatabaseCleaner.clean_with(:truncation)
end
config.before(:each) do
DatabaseCleaner.start
end
config.after(:each) do
DatabaseCleaner.clean
end
end
capybara-webkit
javascript_driverをcapybara-webkitすると処理が高速になりました。
javascriptほとんど使っていないテストですけど、結構違う。
selenium: Finished in 1 minute 31.15 seconds
webkit: Finished in 1 minute 11.55 seconds
capybara-webkitのインストールにはQTが必要。
CentOS 6.4の場合は以下の手順。
/etc/yum.repos.d/ にファイル作成
1
$ sudo vi /etc/yum.repos.d/qt.repo
下記をコピペ、保存。
1
2
3
4
5
6
7
8
9
10
11
12
13
[epel-qt48]
name=Software Collection for Qt 4.8
baseurl=http://repos.fedorapeople.org/repos/sic/qt48/epel-$releasever/$basearch/
enabled=1
skip_if_unavailable=1
gpgcheck=0
[epel-qt48-source]
name=Software Collection for Qt 4.8 - Source
baseurl=http://repos.fedorapeople.org/repos/sic/qt48/epel-$releasever/SRPMS
enabled=0
skip_if_unavailable=1
gpgcheck=0
1
2
3
4
5
6
7
8
インストール
yum install qt48-qt-webkit-devel
シンボリックリンク
ln -s /opt/rh/qt48/root/usr/include/QtCore/qconfig-64.h /opt/rh/qt48/root/usr/include/QtCore/qconfig-x86_64.h
実行
source /opt/rh/qt48/enable
export PATH=/opt/rh/qt48/root/usr/lib64/qt4/bin/${PATH:+:${PATH}}
その他のOS、バージョンは下記参照。
Installing Qt and compiling capybara webkit · thoughtbot/capybara-webkit Wiki · GitHub
テスト
テストの記述自体はこんな感じ。
js: true オプションを忘れずに。
1
2
3
4
5
6
7
describe "User page", js: true do
before do
sign_in user
visit user_path(user)
end
it { should have_content('User profile') }
end
以上です。
いろいろとやることがありますが、
一度セットアップするだけなので、頑張りましょー。
参考
thoughtbot/capybara-webkit · GitHub
bmabey/database_cleaner · GitHub
Headless, a Ruby wrapper for Xvfb – gem, headless, Ruby, rubygems, Xvfb – Leonid Shevtsov
Configuring database_cleaner with Rails, RSpec, Capybara, and Selenium | Virtuous Code
RSpecとCapybaraでJavaScript/Ajaxをテストする - Rails 雑感 - Ruby on Rails with OIAX