2011年12月5日月曜日

いまこそ Ruby の力じゃ! Capybara を使え!!!

この記事はRuby Advent Calendar jp: 2011 : ATNDの4日目です。前日は@hiro_asariさんのRubySpec を走らせるでした。
こんにちは、最近コミットできていない幽霊Rubyコミッタとなりつつある@takano32です。はやく復帰できるようリハビリしています。

さて、今日は Capybara というものを使ってWebでのテストなどを自動化する方法について簡単に説明したいと思います。
と、いいたいところなのですが、面倒なので説明は特に設けることなく、コメントとして説明を入れました。
なんか不足しているモジュールとかがあって走らないようでしたら、空気を読んで gem install hoge すれば動くんじゃないかな。たぶん。

本来はWebサービスのテストなどに使うのですが、今回は分かりやすいように日記やAdvent Calendarで使っているみんなも大好きな「はてな」に自動でログインするスクリプトを書いてみました。

#! /usr/bin/env ruby
# vim: set et sts=2 sw=2 ts=2 fdm=marker ft=ruby :
# author: takano32 <tak@no32 dot tk>
#
require 'rubygems'
require 'pit'
# ブラウザの起動とかを見えないようにできるけど、Xvfbとか必要
# Darwinじゃ使えないかもしれない。
# require 'headless'
require 'capybara'
# capybaraで書いたロジックを実行するWebDriverとしてMechanizeも選べる。
#require 'capybara/mechanize'
require 'capybara/dsl'
require 'uri'
# visit とか with とか fill_in みたいなのが簡単に呼べる。
# きちんと名前空間とか指定する派の人はインクルード不要
include Capybara::DSL
# まあ、コミットしたりするときにパスワードコミットしちゃうとアレ。
config =
Pit.get("hatena",
:require => {
'login-name' => 'your hatena login name',
'password' => 'your hatena password',
})
# 今回は Selenium WebDriver で動かします。
# みためにもモリモリ動いて面白いですし。
Capybara.run_server = false
Capybara.default_driver = :selenium
# ログインのページにジャンプします。
visit('https://www.hatena.ne.jp/login')
# ログインフォームについての処理をブロックで書ける。
within('form') do
# はてなIDとパスワードを自動入力します。
fill_in 'login-name', :with => config['login-name']
fill_in 'password', :with => config['password']
# ログインボタンを探してクリック
find('input.submit').click
end
# ログイン完了!を確認するために15秒くらい待ってみますか。
sleep 15

こんなかんじで気軽に記述することができます。ヤバイですね。
特にヤバイかなぁ、ってポイントをふたつほどあげてみます。

  • Capybara.register_driver で Android端末などのUser-Agentを使うことができる
    • 「どうせ高度なアクセスはAndroidからはこないだろう」って思ってるサイトは危険かもしれません。ってーか、危険ですよ。
  • val = evaluate_script('JavaScriptVariable') のような記述をするとJavaScriptの変数がRubyの変数として使える。
    • JavaScriptの変数の中に次のサイトへの遷移のURLを入れていたりしてませんかね。危険ですよ!普通にJavaScriptの変数にアクセスしてブラウザの訪問先を変えたりできます。
今回は Ruby でブラウザの自動操作などができる Capybara を紹介してみました。最後に危険という話ばかりしていますが、よい子のみなさんはテストなどに使いましょう。ダメ、絶対。

5日目はZonu.EXE, tadsan.による記事の予定です。楽しみですね!

1 件のコメント: