LoginSignup
12
11

More than 5 years have passed since last update.

Ruby on Rails チュートリアルって長いのでサマリー(3章)〜RSpecとレイアウトテンプレート〜

Last updated at Posted at 2015-02-19

Ruby on Rails チュートリアル
http://railstutorial.jp/

前提

  • Mac OS X Yosemite
  • Homebrewは入ってる
  • gemは入ってる
  • gitとかHerokuとかruby以外でも使うものは知ってる

準備

アプリ作成

RSpecを使うため、--skip-test-unitオプションでTest::Unitのtestディレクトリを作成しない。

cd rails_projects
rails new sample_app --skip-test-unit
cd sample_app

Gemfile更新とbundle

RSpec、Capybaraのために必要なものを入れる。

Gemfile
# 追加(HerokuデプロイでWARNINGがでるから)
ruby '2.2.0'

# gem 'sqlite3'
group :development, :test do
  gem 'sqlite3'
  gem 'rspec-rails'
end

# 追加
group :production do
  gem 'pg'
  gem 'rails_12factor'
end

# 追加
group :test do
  gem 'selenium-webdriver'
  gem 'capybara'
end

# gem 'sdoc', '~> 0.4.0', group: :doc
group :doc do
  gem 'sdoc', require: false
end
bundle install --without production
bundle update
bundle install

セッション変数暗号化の秘密トークン(secret token)更新

以下を追加する。

config/initializers/secret_token.rb
# Be sure to restart your server when you modify this file.

# Your secret key is used for verifying the integrity of signed cookies.
# If you change this key, all old signed cookies will become invalid!

# Make sure the secret is at least 30 characters and all random,
# no regular words or you'll be exposed to dictionary attacks.
# You can use `rake secret` to generate a secure secret key.

# Make sure your secret_key_base is kept private
# if you're sharing your code publicly.
require 'securerandom'

def secure_token
  token_file = Rails.root.join('.secret')
  if File.exist?(token_file)
    # Use the existing token.
    File.read(token_file).chomp
  else
    # Generate a new token and store it in token_file.
    token = SecureRandom.hex(64)
    File.write(token_file, token)
    token
  end
end

SampleApp::Application.config.secret_key_base = secure_token

.secretを公開してしまわないように.gitignoreを設定する。

# Ignore bundler config.
/.bundle

# Ignore the default SQLite database.
/db/*.sqlite3
/db/*.sqlite3-journal

# Ignore all logfiles and tempfiles.
/log/*.log
/tmp

# Ignore other unneeded files.
doc/
*.swp
*~
.project
.DS_Store
.idea
.secret

RSpecを使うように設定

JavaScriptランタイムがインストールされていないというエラーが表示された場合は、Gemfileのgem 'therubyracer', platforms: :ruby部分のコメントアウトをはずしてbundle installするといいらしい。
チュートリアルにはNode.jsをインストールするのがおすすめと書いてある。

rails generate rspec:install

commit

git init
git add .
git commit -m "Initial commit"

静的ページ作成

StaticPagesコントローラーをつくる。
アクションはhomeとhelpをつくる。

rails generate controller StaticPages home help --no-test-framework

以下のファイルを確認。
MVCが命名規約で紐付けられていることに注意。

  • config/routes.rb
  • app/controllers/static_pages_controller.rb
  • app/views/static_pages/home.html.erb
  • app/views/static_pages/help.html.erb

(Tips)railsコマンドで作成したものを元に戻す

rails generate xxx
=>
rails destroy xxx

rake db:migrate
=>
rake db:rollback
or
rake db:migrate VERSION=0
※バージョンを指定して戻す

確認

rails s
http://localhost:3000/static_pages/home
http://localhost:3000/static_pages/help

コミット

git add .
git commit -m "Add a StaticPages controller"

TDD

gitの使い方的なこととか、TDDの説明的なこととかは省略。

結合テストの作成

rails generate integration_test static_pages

RED(失敗するテスト)#1 home

テストコードの修正。
この段階では、細かいところは気にしないで、何となく何をしてるかわかればいい。
仕様が変わったらしいので、チュートリアルからコードを変更。
参考:https://www.relishapp.com/rspec/rspec-rails/v/3-1/docs/feature-specs/feature-spec

spec/requests/static_pages_spec.rb
require "rails_helper"

feature "Home page" do
  scenario "should have the content 'Sample App'" do
    visit '/static_pages/home'
    expect(page).to have_content('Sample App')
  end
end

Capybara DSLをRailsヘルパーファイルに追加する。
チュートリアルではRSpecヘルパーに書くことになっているが、仕様が変わったらしい。

spec/rails_helper.rb
RSpec.configure do |config|
  # 追加
  config.include Capybara::DSL
end

Capybaraの仕様が変わったらしいのでフォルダ名を変更
http://programming.ironsand.net/2014/how-to-solve-capypara-undefined-method-visit/

mv spec/requests/ spec/features

RSpecの実行

bundle exec rspec spec/features/

テストエラーになる。

GREEN(テストをとおす)#1 home

コンテンツにSample Appを追加してテストをとおす。

app/views/static_pages/home.html.erb
<h1>Sample App</h1>
<p>
    This is the home page for the
  <a href="http://railstutorial.jp/">Ruby on Rails Tutorial</a>
    sample application.
</p>

RSpecの実行

bundle exec rspec spec/features/

テストが成功する。

RED(失敗するテスト)#2 help

以下を追加

spec/requests/static_pages_spec.rb
feature "Help page" do
  scenario "should have the content 'Help'" do
    visit '/static_pages/help'
      expect(page).to have_content('Help')
  end
end

RSpecの実行

bundle exec rspec spec/features/

テストエラーになる。

GREEN(テストをとおす)#2 help

app/views/static_pages/help.html.erb
<h1>Help</h1>
<p>
  Get help on the Ruby on Rails Tutorial at the
  <a href="http://railstutorial.jp/help">Rails Tutorial help page</a>.
  To get help on this sample app, see the
  <a href="http://railstutorial.jp/book">Rails Tutorial book</a>.
</p>

RSpecの実行

bundle exec rspec spec/features/

テストが成功する。

RED(失敗するテスト)#3 about

以下を追加。

spec/requests/static_pages_spec.rb
feature "About page" do
  scenario "should have the content 'About Us'" do
    visit '/static_pages/about'
    expect(page).to have_content('About Us')
  end
end

RSpecの実行

bundle exec rspec spec/features/

テストエラーになる。
No route matches [GET] "/static_pages/about"と怒られるので、routesを追加。

config/routes.rb
get "static_pages/about"

RSpecの実行

bundle exec rspec spec/features/

テストエラーになる。
The action 'about' could not be found for StaticPagesControllerと怒られるので、controllerにaboutアクションを追加。

app/controllers/static_pages_controller.rb
def about
end

RSpecの実行

bundle exec rspec spec/features/

テストエラーになる。
Missing template static_pages/aboutと怒られる。

GREEN(テストをとおす)#3 about

viewにaboutビューを追加。

app/views/static_pages/about.html.erb
<h1>About Us</h1>
<p>
  The <a href="http://railstutorial.org/">Ruby on Rails Tutorial</a>
  is a project to make a book and screencasts to teach web development
  with <a href="http://rubyonrails.org/">Ruby on Rails</a>. This
  is the sample application for the tutorial.
</p>

RSpecの実行

bundle exec rspec spec/features/

テストが成功する。

レイアウトテンプレートを使ったリファクタリング

RED

以下のようにタイトルのテストを追加(HelpとAboutは省略)。

spec/requests/static_pages_spec.rb
feature "Home page" do
  scenario "should have the content 'Sample App'" do
    visit '/static_pages/home'
    expect(page).to have_content('Sample App')
  end

  scenario "should have the title 'Home'" do
    visit '/static_pages/home'
    expect(page).to have_title("Ruby on Rails Tutorial Sample App | Home")
  end
end

RSpecの実行

bundle exec rspec spec/features/

テストエラーになる。

GREEN

レイアウトテンプレートを修正。

  • <%= yield %>部分に各ビューの内容が挿入される
  • <%= yield(:title) %>部分は:titleというラベルを表示している。:titleラベルは、provide(:title, 'foo')のように各ビューからも設定できる。
app/views/layouts/application.html.erb
<!DOCTYPE html>
<html>
<head>
  <title>Ruby on Rails Tutorial Sample App | <%= yield(:title) %></title>
  <%= stylesheet_link_tag    "application", media: "all",
                                            "data-turbolinks-track" => true %>
  <%= javascript_include_tag "application", "data-turbolinks-track" => true %>
  <%= csrf_meta_tags %>
</head>
<body>

<%= yield %>

</body>
</html>

Viewに:titleラベルの設定を追加する(help, aboutは省略)。

app/views/static_pages/home.html.erb
<% provide(:title, 'Home') %>

RSpecの実行

bundle exec rspec spec/features/

テストが成功する。

commit

git add .
git commit -m "Finish static pages"

RSpecの高度なセットアップ

Guard, Sporkは試してないので省略。

Sublime TextでRSpecを実行

Preferences => Package Control => install
=> RubyTest

Command-Shift-Rでテストを実行。

私の場合は、うまく動かなくて、次の対応をしました。

1.rspecのパス設定

以下のコマンドでRSpecがみつからない。

which rspec

rbenvで環境構築した場合は以下のコマンドが必要らしい。

rbenv rehash
rspec -v
which rspec

2.SublimeにRSpecのパスを設定する。

Command-Shift-Rでテストを実行すると、$HOME/.rbenv/bin/rspecを探そうとしている。
パスを設定すればよいらしい。

Preferences => Package Settings => RubyTest => Settings - User

{
  "run_rspec_command": "$HOME/.rbenv/shims/rspec {relative_path}",
  "run_single_rspec_command": "$HOME/.rbenv/shims/rspec {relative_path}"
}
12
11
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
11