Rails チュートリアルの続き, 静的なページの作成と Rspec によるテスト駆動開発

シェアする

前回のチュートリアルの続き。

Learn Web Development with the Ruby on Rails Tutorial | A Demo App の 3.1, 3.2 をやっていく。

Sponsored Links

静的なページの作成

静的なページを扱うためのコントローラを作成する。

$ bundle exec rails generate controller StaticPages home help --no-test-framework
      create  app/controllers/static_pages_controller.rb
       route  get "static_pages/help"
       route  get "static_pages/home"
      invoke  erb
      create    app/views/static_pages
      create    app/views/static_pages/home.html.erb
      create    app/views/static_pages/help.html.erb
      invoke  helper
      create    app/helpers/static_pages_helper.rb
      invoke  assets
      invoke    coffee
      create      app/assets/javascripts/static_pages.js.coffee
      invoke    scss
      create      app/assets/stylesheets/static_pages.css.scss

--no-test-framework を指定したのはこの後自分でテスト行う為?

ちなみに generate controller したものは destroy controller で削除できる。

$ bundle exec rails destroy controller StaticPages index help

controller を追加したら config/routes.rb に以下のように変更がある。

DemoApp::Application.routes.draw do
  get "static_pages/home"
  get "static_pages/help"
...
end

static_pages/home にアクセスしたら以下のように表示されるはず。

app/controller/static_pages_controller.rb は以下のようになっている。

class StaticPagesController < ApplicationController
  def home
  end

  def help
  end
end

空のメソッドは一件何もしないように見えるが、このクラスは Rails が提供する ApplicationController を継承している為、Rails として動作する。ユーザが /static_pages/home にアクセスした際に Rails は StaticPages コントローラの home メソッドを実行し、View ( MVC の V ) を表示する。

Rails コマンドによって作成された View は app/views/static_pages/home.html.erb にある

<h1>StaticPages#home</h1>
<p>Find me in app/views/static_pages/home.html.erb</p>

Test driven development

テスト駆動開発 (てすとくどうかいはつ、test-driven development; TDD) とは、プログラム開発手法の一種で、プログラムに必要な各機能について、最初にテストを書き(これをテストファーストと言う)、そのテストが動作する必要最低限な実装をとりあえず行った後、コードを洗練させる、という短い工程を繰り返すスタイルである。

テスト駆動開発 - Wikipedia

というわけで Rails でもやってみる。

Gemfile を書き換える

Gemfile を書き換えて test で使用するパッケージを入れます。ここでは rspec を使用します。

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

group :test do
    gem 'selenium-webdriver', '2.0'
    gem 'capybara'
end

Gemfile 書き換えたら bundle update します。bundle exec bundle update ってやったら出来なかったので bundle update を先にしたんですけど大丈夫ですかねぇ・・・

$ bundle update
$ bundle exec bundle update

$ bundle exec rails generate rspec:install
      create  .rspec
       exist  spec
      create  spec/spec_helper.rb

rspec 自体は入ったようなのでテストを作ります

$ bundle exec rails generate integration_test static_pages
      invoke  rspec
      create    spec/requests/static_pages_spec.rb

spec/requests/static_pages_spec.rb の中は以下のような感じ

require 'spec_helper'

describe "StaticPages" do
  describe "GET /static_pages" do
    it "works! (now write some real specs)" do
      # Run the generator again with the --webrat flag if you want to use webrat methods/matchers
      get static_pages_index_path
      response.status.should be(200)
    end
  end
end

これを以下のように書き換えます。

require 'spec_helper'

describe "Static pages" do
    describe "Home page" do
        it "should have the content 'Sample App'" do
            visit '/static_pages/home'
            expect(page).to have_content('Sample App')
        end
    end
end

細かい事はわかってないので省略するが、 /static_pages/home にアクセスしたら 'Sample App' という文言がページにある事を期待している、という意味になる。

次に 上記コードにある page を使うために Capybara DSL を RSpec helper ファイルに追加します。

...
RSpec.configure do |config|
  ...
  config.include Capybara::DSL
end

書いたらテストを実行してみよう。

以下のような表記でなく、スタックトレースが出るようなエラーが出た場合は、エラーメッセージをよく見て対応しよう。自分の場合は、'rake db:migrate RAILS_ENV=test' を実行すると良いみたいな文言がエラーと共に表示されたので実行した後以下のようにテストが動いた。

$ bundle exec rspec spec/requests/static_pages_spec.rb
F

Failures:

  1) Static pages Home page should have the content 'Sample App'
     Failure/Error: expect(page).to have_content('Sample App')
       expected #has_content?("Sample App") to return true, got false
     # ./spec/requests/static_pages_spec.rb:17:in `block (3 levels) in <top (required)>'

Finished in 0.82028 seconds
1 example, 1 failure

Failed examples:

rspec ./spec/requests/static_pages_spec.rb:15 # Static pages Home page should have the content 'Sample App'

Randomized with seed 18838

無事テストに失敗したのでテストに通る様に app/views/static_pages/home.html.erb を書き換える。

<h1>Sample App</h1>
<p>this is the home page for the Ruby on Rails Tutorial sample application.</p>

そして再度実行する。

$ bundle exec rspec spec/requests/static_pages_spec.rb
.

Finished in 0.15423 seconds
1 example, 0 failures

Randomized with seed 52655

無事テストに通過しました。

help ページについても同じように書く。

TDD でページを追加する

About ページを Static pages に追加します。

まずはテストを書きます。

  ...
  describe "About page" do

    it "should have the content 'About Us'" do
      visit '/static_pages/about'
      expect(page).to have_content('About Us')
    end
  end

そしてテストを実行。

$ bundle exec rspec spec/requests/static_pages_spec.rb
Failures:
  1) Static pages About page should have the content 'About Us'
     Failure/Error: visit '/static_pages/about'
     ActionController::RoutingError:
       No route matches [GET] "/static_pages/about"
     # ./spec/requests/static_pages_spec.rb:30:in `block (3 levels) in <top (required)>'

もちろん失敗します。
エラーメッセージ内に "No route matches [GET] "/static_pages/about" とあるのでまずはルーティングを設定します。

about ページのルーティングの追加

まずルーティングを修正します。
config/routes.rb を開いて以下のように about を追加します。

DemoApp::Application.routes.draw do<
  get "static_pages/home"<
  get "static_pages/help"<
  get "static_pages/about"<
  resources :microposts<
...

再度テストを実行してみます。

 $ bundle exec rspec spec/requests/static_pages_spec.rb
Failures:
  1) Static pages About page should have the content 'About Us'
     Failure/Error: visit '/static_pages/about'
     AbstractController::ActionNotFound:
       The action 'about' could not be found for StaticPagesController
     # ./spec/requests/static_pages_spec.rb:30:in `block (3 levels) in <top (required)>'

こんどは "AbstractController::ActionNotFound" といわれました。なのでアクションを追加します。app/controllers/static_pages_controller.rb を開いて以下のように about を追加します。

class StaticPagesController < ApplicationController
  def home
  end

  def help
  end

  def about
  end
end

そしてまたテストを実行します。

$ bundle exec rspec spec/requests/static_pages_spec.rb
Failures:
  1) Static pages About page should have the content 'About Us'
     Failure/Error: visit '/static_pages/about'
     ActionView::MissingTemplate:
       Missing template static_pages/about, application/about with {:locale=>[:en], :formats=>[:html], :handlers=>[:erb, :builder, :raw, :ruby, :jbuilder, :coffee]}. Searched in:
         * "/home/ryomatsu/public_html/ryomatsu.sillca.com/rortest/demo_app/app/views"
     # ./spec/requests/static_pages_spec.rb:30:in `block (3 levels) in <top (required)>'

今度は "Missing template" といわれました。テンプレートを追加します。

テンプレートのファイル名は app/views/static_pages/about.html.erb ですのでこれを新規作成し、以下のようにします。

<h1>About Us</h1>
<p>this is a Ruby on Rails tutorial page</p>

そしてまたテストを実行します。

$ bundle exec rspec spec/requests/static_pages_spec.rb

Finished in 0.17406 seconds
3 examples, 0 failures

Randomized with seed 22802

テストに通過しました。ブラウザで /static_pages/about にアクセスすると作成した About ページが表示されるはずです。

Sponsored Link

シェアする

フォローする