Ruby 簡単なテスト駆動開発とリファクタリング
テスト駆動開発とリファクタリングを行いました
重要なとこをまとめてみました
まず静的なページに対する結合テスト(request spec) を生成します
$ rails generate integration_test static_pages invoke rspec create spec/requests/static_pages_spec.rb
static_pages_spec.rbが生成されました
中身はこんな感じになっていて
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
it "…" doで始まるのがテストですね
visit '/static_pages/home'
上の行は、Capybaraのvisit機能を使って、ブラウザでの/static_pages/homeURLへのアクセスをシミュレーションします。
expect(page).to have_content('Sample App')
その次の行 (上のコード) では、これもCapybaraが提供するpage変数を使って、アクセスした結果のページに正しいコンテンツが表示されているかどうかをテストしています。
ちなみにテストが正常に実行されるようにするためにはspec_helper.rbに
RSpec.configure do |config|
これを追加する必要があります
実際にテストを行ってみます
$ bundle exec rspec spec/requests/static_pages_spec.rb
bundle execをrspecのコマンドの前に置くことで、Gemfile内で定義された環境でRSpecが実行されるように、明示的に指示することができるみたいです。
まずこれを実行するとテストが失敗します
Failure / Error expect (page).to have_content('Sample App') ........
... app/views/static_pages/home.html.erb
...
1 example, 1 failure
間省きますがこんな感じででます
一般的にはこれを「赤色 (Red)」
パスするコードを「緑色 (Green)」と言うそうです
テストにパスするHomeページ用コードを書きます
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>
見出しがSample Appに変更されたため上のコードはパスします
もう一度見てみると
$ bundle exec rspec spec/requests/static_pages_spec.rb
Finished in.......
1 example, 0 failures
.......
とでます
ちなみに同じようなhelpページとaboutページを追加して
<!DOCTYPE html> <html> <head> <title>Ruby on Rails Tutorial Sample App | Home</title> </head> <body> <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> </body> </html>
このようなHTML構造で書いてます
これは
・ページのタイトルがどれもほぼ同じ。
・“Ruby on Rails Tutorial Sample App” が3つのタイトルで共通している。
・HTMLの構造全体が各ページで重複している。
このコードはDRYの原則に反しているのでまとめます
まず埋め込みrubyを使ってhome.html.erbビューのタイトルを直していきます
<% provide(:title, 'Home') %> <!DOCTYPE html> <html> <head> <title>Ruby on Rails Tutorial Sample App | <%= yield(:title) %></title> </head>
ERbと呼ばれている、Rubyの埋め込みの例です
※HTMLビューのファイルの拡張子が.html.erbとなっている理由
provide関数で関連づけてyield関数で挿入します
ちなみに<% ... %>書くと単に実行するだけで
<%= ... %>結果がテンプレートに挿入されます
<%= ... %>はphpで言うところのechoですね
同様に他のページでも編集していきます。
ここで各ページをみていくとタイトルをのぞいてだいたいこーなってます
<% provide(:title, 'Foo') %> <!DOCTYPE html> <html> <head> <title>Ruby on Rails Tutorial Sample App | <%= yield(:title) %></title> </head> <body> Contents </body> </html>
同じにつくったので同じ構造になってる思いますww
Railsには、共通の構造をまとめるためのapplication.html.erbという
特別なレイアウトファイルがあるみたいなので使ってみます。
デフォルトタイトルを埋め込みRubyのコードに差し替えます。
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>
<%= yield %>は各ページの内容をレイアウトに挿入するためのものです。
/static_pages/homeにアクセスすると、
home.html.erbの内容がHTMLに変換され、<%= yield %>の位置に挿入されるみたいです
下のこれはそれぞれにインクルードするためのものです
<%= stylesheet_link_tag ... %> <%= javascript_include_tag "application", ... %> <%= csrf_meta_tags %>
ではhome.html.erbのHTML構造を抜くとこんな感じになります
<% provide(:title, 'Home') %> <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>
まとめるのが難しかったためほとんどコピペのような形になってしまいました>_<