The RSpec Book用にVagrant環境を作成し、写経してみた

RSpecの使い方に慣れるため、評判の良い「The RSpec Book」を写経しました。


手を動かすチュートリアルとしては、Codebreakerというゲームと、Railsの2種類あり、それぞれの作り方がとても参考になりました。
特に、リファクタリングの方法や考え方まで記載されていたので、独学で進めている自分にはありがたかったです。


ただ、本を写経するのに必要な環境が少々古かったことから、Vagrantで環境を作ってから写経をやりましたので、その時の内容をメモしておきます。

The RSpec Book (Professional Ruby Series)

The RSpec Book (Professional Ruby Series)



写経の方法

以下を参考に(というかそのまま)、git(と途中からbranch)を使って写経しました。
技術書の写経 - wyukawa’s blog

1. git checkout -b ブランチ名 で章ごとにブランチを切ってコミットする
2. 章が終わったら、 git checkout master でmasterに戻る
3. git merge ブランチ名 でマージする
4. git tag タグ名 でタグをつける
5. 上記1.〜4.を繰り返す
全て終わったら、git push で --allや--tagsオプションを使って、githubへとpush

写経時の補足

19章以降で使うGemfileについては、以下の記事がとても参考になりました。ありがとうございました。
今頃「The RSpec Book」の第19章(Railsのテスト)以降を試すには - Qiita


また、本の19章以降でRailsを扱いますが、さらっと書いてあったところでもRails力がない自分には少々悩んだため、その部分を補足しておきます。

p364 の補足

本文以外に、「app/model/message.rb」の「validates_presence_of」へ「:text」を追加しないとエラーになります。

class Message < ActiveRecord::Base
  validates_presence_of :title, :text
end
p371 補足

user_example*_spec.rb等は、元々あるuser_spec.rbに上書きして進めることにします。説明のためにファイル名をつけていただけと考えました。



p375 マイグレーションの補足
$ script/rails generate migration AddSenderidToMessage sender_id:integer
      invoke  active_record
      create    db/migrate/20140108210604_add_senderid_to_message.rb

$ bundle exec rake db:migrate(in /home/vagrant/rspec/messages)
==  AddSenderidToMessage: migrating ===========================================
-- add_column(:messages, :sender_id, :integer)
   -> 0.0010s
==  AddSenderidToMessage: migrated (0.0013s) ==================================

$ bundle exec rake db:test:prepare(in /home/vagrant/rspec/messages)
p378 マイグレーションの補足
$ script/rails generate model Subscription subscription_id:integer
      invoke  active_record
      create    db/migrate/20140108212337_create_subscriptions.rb
      create    app/models/subscription.rb
      invoke    rspec
      create      spec/models/subscription_spec.rb

$ script/rails generate migration AddSubscriptionidToUser subscription_id:integer
      invoke  active_record
      create    db/migrate/20140108212429_add_subscriptionid_to_user.rb

$ bundle exec rake db:migrate
(in /home/vagrant/rspec/messages)
==  CreateSubscriptions: migrating ============================================
-- create_table(:subscriptions)
   -> 0.0012s
==  CreateSubscriptions: migrated (0.0014s) ===================================

==  AddSubscriptionidToUser: migrating ========================================
-- add_column(:users, :subscription_id, :integer)
   -> 0.0009s
==  AddSubscriptionidToUser: migrated (0.0011s) ===============================

$ bundle exec rake db:test:prepare
(in /home/vagrant/rspec/messages)

ホスト環境とゲスト環境

ホスト環境

Cookbookの依存などの解決が手間なので、Berkshelfを使ってVagrantfileなどを作成します。
なお、全体的にバージョンが少々古いですが、写経がメインなので今回は特に気にしないことにします。

ゲスト(写経)環境
  • Ubuntu 12.04.3のBox (veeweeで作成したBox、記事はこちら)
  • rbenvへRuby1.8.7を入れる
  • vagrant up時に入れておくgem
    • Bundler 1.0.22
    • Rspec 2.0.0
    • Cucumber 0.9.2
  • Sublime Textをインストール(Githubにあったcookbookを利用)
  • Terminalでgitのbranchが見えるように、.bashrcを編集
  • 日本語化は特にしない (必要であれば、vagrant up後に手動で構築)


なお、Berkshelfで作成した写経用のファイルはGitHubに上げておきました。
thinkAmi/the_rspec_book-env · GitHub



ゲスト環境の構築手順

忘れないように手順を残しておきます。

Vagrantプラグインをインストール
d:\TheRSpecBook>vagrant plugin install vagrant-omnibus
Installing the 'vagrant-omnibus' plugin. This can take a few minutes...
Installed the plugin 'vagrant-omnibus (1.2.1)'!

d:\TheRSpecBook>vagrant plugin install vagrant-berkshelf
Installing the 'vagrant-berkshelf' plugin. This can take a few minutes...
Installed the plugin 'vagrant-berkshelf (1.3.7)'!
BundlerでBerkshelfをローカルインストール

Gemfileを作成します。

d:\TheRSpecBook>bundle init
Writing new Gemfile to d:/TheRSpecBook/Gemfile


Gemfileへ記入します。今回のBerkshelfはGitHubではなくRubyGemsにアップされているものを使用しました。

source "https://rubygems.org"

gem 'berkshelf'


Berkshelfをローカルインストールします。

d:\TheRSpecBook>bundle install --path vendor/bundle
〜省略〜
Your bundle is complete!
It was installed into ./vendor/bundle
Berkshelfの実行と各種ファイルの作成
d:\TheRSpecBook>bundle exec berks cookbook the_rspec_book-env
〜省略〜
      create  the-rspec-book/Vagrantfile


各種ファイルのひな形ができたため、以下のファイルを修正します。

  • Berksfile
  • Vagrantfile
  • recipes/default.rb


Berkshelf v3系から記載方法が変更になるようですが、今のところv3系のbetaがとれたリリースはされていないこともあり、v2系の記述で必要なcookbookを指定しておきます。


Vagrantfileには、rbenvに入れるgemの指定と、使用するcookbookの指定をしておきます。
Vagrant用のBoxはローカルにある前提ですが、起動時にWebよりダウンロードすることもできます。


recipes/default.rbには、以下の2つを行うための内容を記載しておきます。

  • GitのbranchをTerminalへ表示
  • Cucumberの0.9.2をUbuntu12.04.3へ入れるための設定


GitのbranchをTerminalへ表示する方法は以下を参考にして記載しました。
ubuntu terminal にgit のブランチ名を表示 - kyos1704活動記

script "show_git_branch" do
  interpreter "bash"
  user        "root"
  code <<-'EOL'
    wget https://raw.github.com/git/git/master/contrib/completion/git-completion.bash -P /home/vagrant
    chmod -R 777 /home/vagrant/git-completion.bash
    echo source /home/vagrant/git-completion.bash >> /home/vagrant/.bashrc
    echo GIT_PS1_SHOWDIRTYSTATE=true >> /home/vagrant/.bashrc

    echo -n export PS1=\' >> /home/vagrant/.bashrc
    echo -n '\[\033[01;32m\]\u@\[\033[01;33m\] \w$(__git_ps1) \[\033[01;34m\]\$\[\033[00m\] ' >> /home/vagrant/.bashrc
    echo \' >> /home/vagrant/.bashrc

    source /home/vagrant/.bashrc
  EOL
end


Rubyのバックスラッシュ記法を有効にしないよう、ヒアドキュメントの開始をシングルクオートで囲っています。
リテラル


また、.bashrcへ出力をワンライナーで記載する方法が分からなかったので、上記のようにシングルクオートを出力する前後で分割しました。


その他、.bashrcに関して、以下を参考にしました。


CucumberをUbuntu12.04.3へ入れるための設定は、Ubuntuに入っているgcc-4.6ではcucumber 0.9.2をインストール時にエラーとなるため、以下を参考に、gcc-4.5へシンボリックリンクを変更します。
[help]Error Installing Gherkin · Issue #139 · cucumber/gherkin · GitHub

package "gcc-4.5" do
  action :install
end

script "change_gcc45" do
  interpreter "bash"
  user        "root"
  code <<-'EOL'
    rm /usr/bin/gcc
    ln -s /usr/bin/gcc-4.5 /usr/bin/gcc
  EOL
end


あとはvagrant upして環境構築は完了です。
たまにChefのCookbookが適用されないこともありましたが、その時はvagrant destroyしてからupすることで適用されたりしますので、あまり気にしないことにしました。

d:\TheRSpecBook>cd the_rspec_book-env
d:\TheRSpecBook\the_rspec_book-env>vagrant up