何度も同じ事しているので貼っておきます(rails3.1対応版)。
capybara/capybara-webkit/headless対応や、capistrano、staging対応、sub uri対応等を追加しています。
./gen.sh アプリ名
で利用できます(ノーエラーハンドリング上等!)
$ cat gen.sh
2011年10月6日木曜日
2011年10月4日火曜日
rails3.1 with rspec-request , capybaraでcookieを取り扱うには
rails3.1とrspec-requestsをcapybaraで利用した際に、cookieの扱い方が分からなかったのでメモしておきます。
ちなみに各プロダクトは下記の組み合わせで確認しました。
rails-3.1.0
rspec-2.6.0
rspec-rails-2.6.1
capybara-1.0.1
# app/controllers/foo_controller.rb
class FooController < ApplicationController
def index
puts cookies["key1"]
cookies["key1"] = '2'
cookies.permanent["key2"] = "3"
end
end
# spec/requests/foo_spec.rb
describe "foo周辺の仕様" do
def cookies
Capybara.current_session.driver.browser.current_session.instance_variable_get(:@rack_mock_session).cookie_jar
end
it "foo/index" do
cookies["key1"] = '1'
visit "/foo/index"
cookies["key1"].should == '2'
cookies["key2"].should == '3'
end
end
上記の検証の過程で、
- cookiesのキー名は文字列でないといけない(シンボルだと上手くいかない)
- cookiesメソッドを上書く必要があり
- permanentでも同じように読める("key2")
ちなみに各プロダクトは下記の組み合わせで確認しました。
rails-3.1.0
rspec-2.6.0
rspec-rails-2.6.1
capybara-1.0.1
2011年9月26日月曜日
capybaraをwebkitやseleniumとかで動かす場合の注意点と解決策
■概要
capybaraとwebkit(たぶんselenium)を利用する際は、capybara側がブラウザとやりとりする為のスレッドを立ち上げる為
RSpec.configure do |config| ... config.use_transactional_fixtures = false endしてfixtureのトランザクション制御をあきらめる必要があります。これでは少し都合が悪いので、 DatabaseCleanerを利用して代用する等行う必要があります。
ところがrailsコアチームのjosevalim氏が解決策をぼそっとつぶやいてました。実際にやってみると上手く動くだけでなく実行速度がかなり改善されました。
■解決策
つぶやきで紹介されている方法は非常に簡単です。
spec_helper(test_helper.rb)で下記の用に追記しましょう。
RSpec.configure do |config|
...
config.use_transactional_fixtures = true
end
# 下記追加
class ActiveRecord::Base
mattr_accessor :shared_connection
@@shared_connection = nil
def self.connection
@@shared_connection || retrieve_connection
end
end
ActiveRecord::Base.shared_connection = ActiveRecord::Base.connection
でいつもどおり$ bundle exec rake spec
して見ましょう。specの実行速度が改善したのでは無いでしょうか?
ね、簡単でしょう!
@josevalim氏に多謝!
2011年9月20日火曜日
spec実行時にdb:test:prepareを呼び出したくない。
■概要
(激しく既出感ありですが。。)何年もrailsやってますが、正しく理解できていなかった事の一つに
rake spec(test)すると、処理の一環としてdb:test:prepareタスクを呼び出す
という挙動があります。
通常問題にならないのですが、db:test:prepareが、db/schema.rbの情報を元にデーターベースを作成する為、railsが認識できないような項目は抜けて落ちてしまいます。
- 関数適用したインデックス
- トリガーやファンクション
- 別スキーマに作ったオブジェクト ...etc
なので
RAILS_ENV=test rake db:drop
RAILS_ENV=test rake db:create
RAILS_ENV=test rake db:migrate
してからrake specする事を前提に、db:test:prepareを呼び出さずにspecを実行する方法を模索しました。
■案1 db:test:prepare自体を書き換える
参照先にそのまんまの解決策が書かれています。
Rakefileでtask削除用のメソッドを用意します(load_tasksの前に!)。
Rake::TaskManager.class_eval do
def remove_task(task_name)
@tasks.delete(task_name.to_s)
end
end
lib/tasks/db/test.rakeとかを作って、実際にタスクを上書きします
Rake.application.remove_task 'db:test:prepare'
namespace :db do
namespace :test do
task :prepare do |t|
# rewrite the task to not do anything you don't want
end
end
end
参考 http://stackoverflow.com/questions/1097845/how-to-prevent-rake-test-to-call-task-dbtestprepare
■案2 自力でspecを実行する
db:test:prepareを壊すのは怖いので...という方にはこのやり方
lib/tasks/spec.rakeとかを作って
require 'rake'
require 'rspec/core/rake_task'
namespace :spec do
RSpec::Core::RakeTask.new('no_prepare_db') do |t|
t.pattern = ['spec/**/*_spec.rb']
end
namespace :no_prepare_db do
%w(controllers helpers lib mailers models requests routing views).each do |dir|
RSpec::Core::RakeTask.new(dir) do |t|
t.pattern = ["spec/#{dir}/**/*_spec.rb"]
end
end
end
end
で、rake spec:no_prepre_dbや、rake spec:no_prepare_db:modelsで、db:test:prepareを呼び出さずに実行できます。参考 http://old.nabble.com/db%3Atest%3Aprepare-interfering-with-rake-spec-pattern-td31075510.html
2011年8月23日火曜日
capybara-webkitを動かす 2011/08/23時点版
■概要
こちらの素晴らしい記事では、capybara-webkitを利用して、headlessでjsが動く環境を紹介されています。
capybara-webkitのこれまでリリースされているバージョン(~0.5.0)では、capybara1.0.0系への依存が解決できない為、抗う方法をご紹介されています。が、0.6.0からは上手く依存関係を解決されるようになりました!
■手順
こちらと同様ですが、Xvfbとqtの当たらしいバージョン(qt47)をインストールしておきます。
qt47にする理由はphantomjsも動かしたいからです ^o^
$ sudo yum -y install firefox ★ seleniumで動かす必要があれば
$ sudo yum -y install xorg-x11-server-Xvfb xorg-x11-fonts*
$ sudo vim /etc/yum.repos.d/atrpms.repo
[atrpms]
name= CentOS-$releasever - ATrpms
baseurl=http://dl.atrpms.net/el$releasever-$basearch/atrpms/testing/
gpgcheck=1
gpgkey=http://ATrpms.net/RPM-GPG-KEY.atrpms
enabled=0
$ sudo rpm --import http://packages.atrpms.net/RPM-GPG-KEY.atrpms
$ sudo yum -y install sqlite --enablerepo=atrpms ★依存関係からインストールする必要がある?
$ sudo yum -y install qt47-devel qt47-webkit qt47-webkit-devel --enablerepo=atrpms
$ sudo ln -s /usr/bin/qmake-qt47 /usr/bin/qmake (コンパイル時に必要とされるので予め作成)
でrailsプロジェクト側で
$ vim Gemfile
$ vim spec/spec_helper.rb
$ HEADLESS=on bundle exec rspec spec/requests/index_spec.rb
こちらの素晴らしい記事では、capybara-webkitを利用して、headlessでjsが動く環境を紹介されています。
capybara-webkitのこれまでリリースされているバージョン(~0.5.0)では、capybara1.0.0系への依存が解決できない為、抗う方法をご紹介されています。が、0.6.0からは上手く依存関係を解決されるようになりました!
■手順
こちらと同様ですが、Xvfbとqtの当たらしいバージョン(qt47)をインストールしておきます。
qt47にする理由はphantomjsも動かしたいからです ^o^
$ sudo yum -y install firefox ★ seleniumで動かす必要があれば
$ sudo yum -y install xorg-x11-server-Xvfb xorg-x11-fonts*
$ sudo vim /etc/yum.repos.d/atrpms.repo
[atrpms]
name= CentOS-$releasever - ATrpms
baseurl=http://dl.atrpms.net/el$releasever-$basearch/atrpms/testing/
gpgcheck=1
gpgkey=http://ATrpms.net/RPM-GPG-KEY.atrpms
enabled=0
$ sudo rpm --import http://packages.atrpms.net/RPM-GPG-KEY.atrpms
$ sudo yum -y install sqlite --enablerepo=atrpms ★依存関係からインストールする必要がある?
$ sudo yum -y install qt47-devel qt47-webkit qt47-webkit-devel --enablerepo=atrpms
$ sudo ln -s /usr/bin/qmake-qt47 /usr/bin/qmake (コンパイル時に必要とされるので予め作成)
でrailsプロジェクト側で
$ vim Gemfile
group :development, :test do ... gem 'capybara', '1.0.1' gem 'capybara-webkit', '0.6.0' gem 'headless', '0.1.0' ... end$ bundle install
$ vim spec/spec_helper.rb
... require "capybara/rails" require "capybara/rspec" ... RSpec.configure do |config| ... end Capybara.javascript_driver = :webkit$ vim spec/support/headless.rb
if %w(yes y on).include?(ENV['HEADLESS'])
require 'headless'
headless = Headless.new
headless.start
at_exit do
headless.destroy
end
end
$ vim spec/requests/index_spec.rb# coding: utf-8
require 'spec_helper'
describe "Index" do
describe "GET /" do
it "/index.html", :js => true do
visit "/"
click_link "About your application’s environment"
page.should have_content("No route matches")
end
end
end
で$ HEADLESS=on bundle exec rspec spec/requests/index_spec.rb
Index
GET /
/index.html
Finished in 4.48 seconds
1 example, 0 failures
という訳でいい感じに実行できました~
2011年8月13日土曜日
ruby1.9時代にrcovは使ってはいけない。simplecovを使おう!
■概要
rubyにおけるテスト網羅率の定番ツールといえばrcovですが、どうもテストの通っている箇所の色付けがおかしいのと網羅率に誤差があると感じてました。
よくよくgithubのrcovのページを見てみると、
NOTE: This fork does not work on Ruby 1.9.x. For coverage on Ruby 1.9 look at SimpleCov. Even if you get results on 1.9 they will probably be inaccurate. Ruby 1.9 has call detection built in for faster, more accurate results.
なんて書いてあります。という訳でSimpleCovを試してみました。
なおこちらで簡単にセットアップできるシェルスクリプト置いてます!
■説明
まずはいつものGemfileに
と記載して
$ bundle install
次にspec/spec_helper.rbに下記コードを追加しましょう。
この時大事なのは実行の早い段階(railsが読み込まれる前!)で下記を実行する必要がある事です。
で
すると、coverageディレクトリ以下にhtmlファイルが出力されます(画像はsimplecovのページより)
このままでも良いのですが、rcovのフォーマットと異なるので、CIに統合するには不便です。そんな時はsimplecov_rcovを利用すると上手く行きます。
spec/spec_helper.rbには、SimpleCovの出力フォーマットを変更するコードを書きます。
※くれぐれも早い段階で読み込んで下さい!
すると見慣れたあのHTMLがcoverage/rcov以下に出力されます。
coverage/rcovをCI(というかjenkins)のrcovレポートの場所として指定してあげると良好な結果が得られます!
ちなみにsimplecov-rcovのページで下記の様な記載があり、網羅率測定有無を切り替える方法があります。
rubyにおけるテスト網羅率の定番ツールといえばrcovですが、どうもテストの通っている箇所の色付けがおかしいのと網羅率に誤差があると感じてました。
よくよくgithubのrcovのページを見てみると、
NOTE: This fork does not work on Ruby 1.9.x. For coverage on Ruby 1.9 look at SimpleCov. Even if you get results on 1.9 they will probably be inaccurate. Ruby 1.9 has call detection built in for faster, more accurate results.
なんて書いてあります。という訳でSimpleCovを試してみました。
なおこちらで簡単にセットアップできるシェルスクリプト置いてます!
■説明
まずはいつものGemfileに
gem 'simplecov', :require => false
と記載して
$ bundle install
次にspec/spec_helper.rbに下記コードを追加しましょう。
この時大事なのは実行の早い段階(railsが読み込まれる前!)で下記を実行する必要がある事です。
require 'simplecov' SimpleCov.start 'rails'
で
$ rake spec
すると、coverageディレクトリ以下にhtmlファイルが出力されます(画像はsimplecovのページより)
このままでも良いのですが、rcovのフォーマットと異なるので、CIに統合するには不便です。そんな時はsimplecov_rcovを利用すると上手く行きます。
group :test do gem 'simplecov', :require => false gem 'simplecov-rcov', :require => false end $ bundle install
spec/spec_helper.rbには、SimpleCovの出力フォーマットを変更するコードを書きます。
require 'simplecov' require 'simplecov-rcov' SimpleCov.formatter = SimpleCov::Formatter::RcovFormatter
※くれぐれも早い段階で読み込んで下さい!
すると見慣れたあのHTMLがcoverage/rcov以下に出力されます。
coverage/rcovをCI(というかjenkins)のrcovレポートの場所として指定してあげると良好な結果が得られます!
ちなみにsimplecov-rcovのページで下記の様な記載があり、網羅率測定有無を切り替える方法があります。
if( ENV['COVERAGE'] == 'on' ) require 'simplecov' require 'simplecov-rcov' SimpleCov.formatter = SimpleCov::Formatter::RcovFormatter ... end $ COVERAGE=on rake specまた複数の出力フォーマットで出力する例もありますので是非見てみて下さい。
2011年1月26日水曜日
rails3とbackbone.jsの組み合わせで利用する2
■概要
前回に引き続き、backbone.jsを利用してjqueryでMVCの世界を、rails3と共に作っていこうと思います。
今回はデータのやり取りをする所までが目標です。
■モデル/コントローラ等を作成する
$ rails g scaffold post title:string body:text published:boolean
$ rake db:migrate
$ rake spec (とりあえずrspecが動くか確認しとく)
$ rake spec:rcov (ついでにrcovが動くか確認しとく)
$ rails s
ここで http://localhost:3000/posts でいつもの画面が表示されてればOK!
■json入出力用にコントローラを修正する
とりあえずjsonでやり取りできるように変更します。params.exceptはbackboneとのやり取りを考慮してます。
■jsonのフォーマットを変更する
このままだと下記の用に"post"が付いてしまうので、backbone側の期待と異なります。
http://localhost:3000/posts.json
=> [{"post":{"body":"a","created_at":"2011-01-19T16:13:47Z","id":1,"published":false,"title":"aa","updated_at":"2011-01-19T16:13:47Z"}}]
http://localhost:3000/posts/1.json
=> {"post":{"body":"a","created_at":"2011-01-19T16:13:47Z","id":1,"published":false,"title":"aa","updated_at":"2011-01-19T16:13:47Z"}}
config/initializers/include_root_in_json.rbの様なファイルを作成し
とすると下記の様な感じでgoodです!
http://localhost:3000/posts.json
=> [{"body":"a","created_at":"2011-01-19T16:13:47Z","id":1,"published":false,"title":"aa","updated_at":"2011-01-19T16:13:47Z"}]
http://localhost:3000/posts/1.json
=> {"body":"a","created_at":"2011-01-19T16:13:47Z","id":1,"published":false,"title":"aa","updated_at":"2011-01-19T16:13:47Z"}
■backbone用のcontorollerを作成
コントローラ/ビューを追加して必要な設定を追加します。
$ vim controllers/home_controller.rb
$ vim config/routes.rb
root => "home#index"
$ rm public/index.html
$ mkdir views/home
■backbone.jsを使ってみる
http://localhost:3000/ を開いて、画面に味気ないalertが表示されればOkay!!
railsのログとDB見てると少しは楽しいかも
次は画面を作っていきましょう!
前回に引き続き、backbone.jsを利用してjqueryでMVCの世界を、rails3と共に作っていこうと思います。
今回はデータのやり取りをする所までが目標です。
■モデル/コントローラ等を作成する
$ rails g scaffold post title:string body:text published:boolean
$ rake db:migrate
$ rake spec (とりあえずrspecが動くか確認しとく)
$ rake spec:rcov (ついでにrcovが動くか確認しとく)
$ rails s
ここで http://localhost:3000/posts でいつもの画面が表示されてればOK!
■json入出力用にコントローラを修正する
とりあえずjsonでやり取りできるように変更します。params.exceptはbackboneとのやり取りを考慮してます。
class PostsController < ApplicationController
respond_to :json
def index
@posts = Post.all
respond_with @posts
end
def show
@post = Post.find(params[:id])
respond_with @post
end
def create
@post = Post.new(params.except(:action, :controller))
respond_to do |format|
if @post.save
format.json { render :json => @post, :status => :created, :location => @post }
else
format.json { render :json => @post.errors, :status => :unprocessable_entity }
end
end
end
def update
@post = Post.find(params[:id])
respond_to do |format|
if @post.update_attributes(params.except(:id, :action, :controller, :created_at, :updated_at))
format.json { head :ok }
else
format.json { render :json => @post.errors, :status => :unprocessable_entity }
end
end
end
def destroy
@post = Post.find(params[:id])
@post.destroy
respond_to do |format|
format.json { head :ok }
end
end
end
■jsonのフォーマットを変更する
このままだと下記の用に"post"が付いてしまうので、backbone側の期待と異なります。
http://localhost:3000/posts.json
=> [{"post":{"body":"a","created_at":"2011-01-19T16:13:47Z","id":1,"published":false,"title":"aa","updated_at":"2011-01-19T16:13:47Z"}}]
http://localhost:3000/posts/1.json
=> {"post":{"body":"a","created_at":"2011-01-19T16:13:47Z","id":1,"published":false,"title":"aa","updated_at":"2011-01-19T16:13:47Z"}}
config/initializers/include_root_in_json.rbの様なファイルを作成し
ActiveRecord::Base.include_root_in_json = false
とすると下記の様な感じでgoodです!
http://localhost:3000/posts.json
=> [{"body":"a","created_at":"2011-01-19T16:13:47Z","id":1,"published":false,"title":"aa","updated_at":"2011-01-19T16:13:47Z"}]
http://localhost:3000/posts/1.json
=> {"body":"a","created_at":"2011-01-19T16:13:47Z","id":1,"published":false,"title":"aa","updated_at":"2011-01-19T16:13:47Z"}
■backbone用のcontorollerを作成
コントローラ/ビューを追加して必要な設定を追加します。
$ vim controllers/home_controller.rb
class HomeController < ApplicationController def index end end
$ vim config/routes.rb
root => "home#index"
$ rm public/index.html
$ mkdir views/home
■backbone.jsを使ってみる
$ vim views/home/index.html.erb
http://localhost:3000/ を開いて、画面に味気ないalertが表示されればOkay!!
railsのログとDB見てると少しは楽しいかも
次は画面を作っていきましょう!
ラベル:
backbonejs,
jquery,
rails,
rspec
2011年1月11日火曜日
rails3とbackbone.jsの組み合わせで利用する1
■概要
backendをrails3にして、backbone.jsを利用する為の手順を残しておきます。
■railsプロジェクトの作成
backendをrails3にして、backbone.jsを利用する為の手順を残しておきます。
■railsプロジェクトの作成
$ rails new demo -T -J -d mysql
demo プロジェクト名
demo プロジェクト名
-T testunitはいらない
-J prototype.jsはいらない
-d mysql データベースはmysql
■gemを追加
$ cd demo
$ vim Gemfile
下記を一番下に追加(本当はバージョンをつけた方が良い)
gem 'jquery-rails'
group :development, :test do
gem 'rspec'
gem 'rspec-rails'
gem 'rcov'
gem 'rcov'
end
$ bundle install
■コードジェネレート
$ rails g rspec:install
$ rails g jquery:install --ui
■まず使えるように編集
$ vim config/database.yml
$ vim app/views/layouts/application.html.erb
文字列エンコーディングを明確に指定する為に下記追加
<meta charset="utf-8"/>
$ vim config/application.rb
jquery-railsに、javascriptのdefaults設定はまかせる(コメントアウトする)
# config.action_view.javascript_expansions[:defaults] = %w()
※これを有効にしたい
$ vim spec/spec_helper.rb
ruby1.9.2でrcovを正しく動作させる為に、下記を一番下に追加
# quick monkey patch for rcov
# http://codefluency.com/post/1023734493/a-bandaid-for-rcov-on-ruby-1-9
if defined?(Rcov)
class Rcov::CodeCoverageAnalyzer
def update_script_lines__
if '1.9'.respond_to?(:force_encoding)
SCRIPT_LINES__.each do |k,v|
v.each { |src| src.force_encoding('utf-8') }
end
end
@script_lines__ = @script_lines__.merge(SCRIPT_LINES__)
end
end
end
$ vim .rspec
spork等で動いてもいい様に下記を追加しておく
--drb
■backbone.jsの準備
$ cd public/javascripts
↓jsファイル取得。ここも本当はバージョンを明示すべきかな
↓jsファイル取得。ここも本当はバージョンを明示すべきかな
$ wget http://documentcloud.github.com/underscore/underscore.js
$ wget http://documentcloud.github.com/underscore/underscore-min.js
$ wget http://documentcloud.github.com/backbone/backbone.js
$ wget http://documentcloud.github.com/backbone/backbone-min.js
$ cd ../..
$ vim app/views/layouts/application.html.erb
backbone.jsを読み込むようにする。下記をhead内に追加
backbone.jsを読み込むようにする。下記をhead内に追加
<%= javascript_include_tag "underscore-min.js", "backbone-min.js" %>
ここまでで準備完了!次は実際にデータの操作をしてみます
20110113 追記
http://d.hatena.ne.jp/nedate/20101004/1286183882を参考にrcovの設定も追加させてもらいました!
■履歴管理開始
$ vim .gitignore (履歴管理しない最低限のものを追加)
.bundle
db/*.db
db/*.sqlite3
db/schema.rb
log/*.log
tmp/
coverage/
*.swp
$ git init
.bundle
db/*.db
db/*.sqlite3
db/schema.rb
log/*.log
tmp/
coverage/
*.swp
$ git init
$ git add .
$ git commit -m "最初のコミット"
■DB作成
$ rake db:create:all
$ rake db:migrate
■起動
$ rails s
ここまでで準備完了!次は実際にデータの操作をしてみます
20110113 追記
http://d.hatena.ne.jp/nedate/20101004/1286183882を参考にrcovの設定も追加させてもらいました!
ラベル:
backbonejs,
jquery,
rails,
rspec
2011年1月4日火曜日
CoffeeScript面白そう2
前回インストールしてみたCoffeeScriptだが、jasmineと組み合わせるとこんな感じで、javascriptのspecが書けた。
describe "String クラスは", ->
str = ""
beforeEach ->
str = "jasmine"
it "split メソッドを持っている", ->
expect(str.split).toBeDefined()
describe "ネストは", ->
it "当然いけます", ->
expect(str).toEqual("jasmine")
オリジナルのjasmine specと比較して良いのは
辺りでしょうか。本気で使うなら課題は
といった所かな。少し考えるか。。
2011/01/04 0:52 追記
変数にrubyっぽく@をつけて(thisとバインド)、上記は
describe "String クラスは", ->
str = ""
beforeEach ->
str = "jasmine"
it "split メソッドを持っている", ->
expect(str.split).toBeDefined()
describe "ネストは", ->
it "当然いけます", ->
expect(str).toEqual("jasmine")
オリジナルのjasmine specと比較して良いのは
- {} とか () とか ; が激減している
- functionって書かなくて良い
- varも書かなくて良い
辺りでしょうか。本気で使うなら課題は
- coffeeの実行(*.coffee -> *.jsにコンパイル)を自動化
- expect ~ toEqualとかをもっと"rspec"らしくしたい
- 上の"str"をrspecっぽく何とかしたい(無理かな?)
といった所かな。少し考えるか。。
2011/01/04 0:52 追記
変数にrubyっぽく@をつけて(thisとバインド)、上記は
describe "String クラスは", ->
beforeEach ->
@str = "jasmine"
it "split メソッドを持っている", ->
expect(@str.split).toBeDefined()
で動くんだ。
ラベル:
bdd,
coffeescript,
jasmine,
rspec
登録:
投稿 (Atom)