The RSpec BookやRailsチュートリアルを終えたタイミングでちょうど Everyday Railsの翻訳本が出たため、今度はこちらを手にとって写経をしてみました。
Everyday Rails - RSpecによるRailsテスト入門 - Leanpub
結論としては、RailsやRSpecを独学で学んでいる初心者に対してとても分かりやすい本で、かつ、今後もバージョンアップに追随していく予定というお得なものでもあったため、購入して正解でした。
感想
原著者のAaron Sumnerさんも手を動かして学ぶことを推奨していることからも、本書を通して写経しやすい構成になっていました。特に、アプリコードにはほとんど手を入れずにテストコードを書き進める形であったため、テストの書き方を学ぶのに集中することができました*1。
他に、RSpecに対する便利な設定方法や詳しく知りたい場合のリンク先も紹介されているため、コンパクトであるにも関わらずRSpecを学習してゆく上で良いとっかかりを得られる本でした。
翻訳に関しても、ベータ版の段階でもそれほど大きな違和感を持つことなく、読み進めることができました。
また、@jnchitoさんをはじめとする翻訳者の方々から次々と進捗状況が出ていたので、どんなものかワクワクしながら発売を待ったりしていました。
なお、書籍の中で示されているけれど自分ではやらなかったこととしては、
- spec/spec_helper.rbにconfig.include FactoryGirl::Syntax::Methodsを追加すること
- 後から振り返った時に、FactoryGirl由来のメソッドかどうか、分かりやすくするため
- expect(..).toの否定形は、「expect(..).to_not」を使うこと
といったところです。
写経環境
今回もWindows上ではなく、VirtualBoxのVM上で行いました。
- Ubutu12.04
- rbenv
- Ruby 2.0.0p353(写経した当時の最新版)
具体的な環境は、前回のエントリのものなります(なお、Rubyはp353を指定していました。ただ、p451でRSpecを動作させてもエラーにはなりませんでした)。
- 写経環境を、vagrant-berkshelf から Vagrant + knife-solo + Berkshelf へと変更した - メモ的な思考的な
- thinkAmi/syakyo_env-ruby · GitHub*3
また、参考までに自分の写経したコードをGitHubにあげておきました。
一番最初のベータ版(2014/2/7発行)を使って写経したため、現在の正式版とは異なるかもしれません。
thinkAmi/everyday_rails_4_0-syakyo · GitHub
写経を進めるにあたり
サンプルコードのclone
Everyday Railsのコードは公開されていますが、テストコードが付属していないブランチ「01_notest」のみをチェックアウトしたかったため、single-branchオプションを利用しました。
git clone -b 01_untested --single-branch https://github.com/everydayrails/rspec_rails_4.git
なお、single-branchオプションは1.7.10以降のバージョンで利用できるのですが、Ubuntu12.04のGitは1.7.9.5であったため、今回はPPAのものを使いました。
参考:git - Clone only one branch - Stack Overflow
自分のGitHubへのpush
git cloneしたものをpushしながら進めるため、以下のようにして自分のGitHubへpushしました。
vagrant@ ~/everydayrails_4_0/rspec_rails_4 (01_untested) $ git remote origin vagrant@ ~/everydayrails_4_0/rspec_rails_4 (01_untested) $ git remote add github https://github.com/thinkAmi/everyday_rails_4_0-syakyo.git vagrant@ ~/everydayrails_4_0/rspec_rails_4 (01_untested) $ git remote -v github https://github.com/thinkAmi/everyday_rails_4_0-syakyo.git (fetch) github https://github.com/thinkAmi/everyday_rails_4_0-syakyo.git (push) origin https://github.com/everydayrails/rspec_rails_4.git (fetch) origin https://github.com/everydayrails/rspec_rails_4.git (push) vagrant@ ~/everydayrails_4_0/rspec_rails_4 (01_untested) $ git push -u github 01_untested Username for 'https://github.com': thinkAmi Password for 'https://thinkAmi@github.com': Counting objects: 250, done. Compressing objects: 100% (190/190), done. Writing objects: 100% (250/250), 39.14 KiB | 0 bytes/s, done. Total 250 (delta 71), reused 154 (delta 36) To https://github.com/thinkAmi/everyday_rails_4_0-syakyo.git * [new branch] 01_untested -> 01_untested Branch 01_untested set up to track remote branch 01_untested from github.
参考: transitive.info - git remote 使い方
悩んだところなどのメモ
bundle installしようとしたら、エラー
p7にて、git cloneしたGemfileを元にbundle installしたところ、以下のエラーが発生しました。
vagrant@ ~/everyday_rails_4_0-syakyo (01_untested *) $ bundle exec rspec rbenv: version `2.0.0' is not installed rbenv: version `2.0.0' is not installed
原因は、.ruby-versionファイルに「2.0.0」とだけ記載されていて、パッチレベルが記載されていなかったため、rbenvで利用するときにエラーとなったようでした。
参考:octopress をアップデートした (.ruby-version が conflict した) 話 - @znz blog
そのため、.ruby-versionファイルにパッチレベルを記載しました。
ruby2.0.0-p353
また、.gitignoreにも .ruby-version を無視するように追加しておきました。
git rm --cached .ruby-version
参考:gitignoreまとめ - maeharin log
p30 「アプリケーションにファクトリを追加する」に伴う作業
p31で、example「it "has a valid factory"」を追加する際、不要になったexample「it "is valid with a firstname, lastname and email"」を削除しておきます。
また、以下の部分をファクトリを使うように修正しておきます。修正を忘れると、p37のコールバックを追加したところでexampleが失敗するようになりました。
- 修正前
describe "fileter last name by letter" do before :each do @smith = Contact.create(firstname: 'John', lastname: 'Smith', email: 'jsmith@example.com') @jones = Contact.create(firstname: 'Tim', lastname: 'Jones', email: 'tjones@example.com') @johnson = Contact.create( firstname: 'John', lastname: 'Johnson', email: 'jjohnson@example.com') end ...
- 修正後
describe "fileter last name by letter" do before :each do @smith = FactoryGirl.create(:contact, lastname: 'Smith', email: 'jsmith@example.com') @jones = FactoryGirl.create(:contact, lastname: 'Jones', email: 'tjones@example.com') @johnson = FactoryGirl.create(:contact, lastname: 'Johnson', email: 'jjohnson@example.com') end ...
p79 scenarioに js: true を追加したexampleを実行するとエラー
これは自分の環境由来のものなので、他の環境では発生しないかもしれませんが、2つの原因により発生しました。
1. /etc/hosts ファイル由来
自分がVagrantで環境を作ったせいかもしれませんが、実行するとしばらく動作が停止した後、以下のエラーが発生しました。
Failures: 1) About BigCo model toggles display of the model about display Failure/Error: visit root_path Selenium::WebDriver::Error::WebDriverError: unable to bind to locking port 7054 within 45 seconds
原因は、/etc/hosts ファイルの設定内容に問題があったためです。
参考:Ruby - unable to bind to locking port 7054 within 45 seconds (Selenium::WebDriver::Error::WebDriverError) - Stack Overflow
そのため、以下の通りに、/etc/hosts ファイルを修正します。
修正前
127.0.0.1 everydayrails-4.0 everydayrails-4 127.0.1.1 everydayrails-4.0 everydayrails-4
修正後
127.0.0.1 localhost 127.0.1.1 everydayrails-4.0 everydayrails-4
2. selenium-webdriver gemのバージョン由来
写経環境のFirefoxを26にアップデートした後にRSpecでテストをしたところ、Firefoxは起動するものの何も動作せず、以下のエラーが発生しました。
1) About BigCo model toggles display of the model about display Failure/Error: visit root_path Selenium::WebDriver::Error::WebDriverError: unable to obtain stable firefox connection in 60 seconds (127.0.0.1:7055)
原因は、現時点のGitHub上の最新コミット、および自分が写経したベータ版(2014/2/7版)では、Gemfileで「gem "selenium-webdriver", "~> 2.35.1"」と古いバージョンをしているためです。
参考:selenium - unable to obtain stable firefox connection in 60 seconds (127.0.0.1:7055) ubuntu - Stack Overflow
そのため、上記のリンクにあるように「2.38.0」と指定するか、正式版のp7に記載されている「2.39.0」を指定すれば、正しく動作するようになりました。