13
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Rails Tutorialの知識から【ポートフォリオ】を作って勉強する話 #2 RSpec導入編

Last updated at Posted at 2019-08-04

こんな人におすすめ

  • プログラミング初心者でポートフォリオの作り方が分からない
  • Rails Tutorialをやってみたが理解することが難しい

前回:#1 準備編
次回:#3 Bootstrap4, jQueryプラグイン導入編

今回の流れ

  1. 今回のイメージを理解する
  • トップページのダミーを作る
  • RSpecを導入する
  • ヘルパーテストを書く
  • ブラウザテストの雰囲気を掴む

※ この記事は、ポートフォリオを作る理由をweb系自社開発企業に転職するためとします。
※ 2020年3月28日、記事を大幅に更新しました。

今回のイメージを理解する

始めに、簡単なRailsの動作とRSpecを説明するためダミーページを作ります。
続いて、ページによってタイトルが変わるfull_titleメソッドを作ります。
続いて、RSpecを導入します。
最後に、full_titleとブラウザのテストを書きます。

以上です。

トップページのダミーを作る

まずはRails Tutorialの3~4章にならってトップページのダミーを作ります。
これはRails TutorialのテストをMinitestからRSpecに変更する際、差分をわかりやすくするためです(実際のトップページは#3から作ります)。

ダミーページには以下の要素を含みます。

  • ダミーページのルーティングとMVCを整える
  • タイトルを動的に変更するヘルパーを作る

ダミーページのルーティングとMVCを整える

ダミーページのルーティングとMVC(Model, View, Controller)を整えます。
各用語の説明はRails Tutorialに譲りますが、ざっくりと言うと以下の通りです。

  • Model → データを格納する
  • View → Web上に表示する
  • Controller → モデルとビューを制御する
  • ルーティング → リクエストに対するコントローラーの割り当てをする

それではこれらを作成します。

ルーティング

まずはルーティングをします。
ルートにはstatic_pagesコントローラーのhomeアクションを割り当てます。
その他にはstatic_pagesコントローラーのaboutアクションを割り当てます。

config/routes.rb
Rails.application.routes.draw do
  root 'static_pages#home'
  get '/about', to: 'static_pages#about'
end

Controller

ジェネレーターでコントローラーを作成します。
この時、自動的にhome, aboutアクションに対応するビューも作成されます。

shell
$ rails g controller StaticPages home about
app/controllers/static_pages_controller.rb
class StaticPagesController < ApplicationController

  def home
  end

  def about
  end
end

View

ビューのタイトルはRails Tutorialで作成したfull_titleメソッドを使っています。
こちらは後述します。

app/views/layouts/application.html.erb
<!DOCTYPE html>
<html>
  <head>
    <title><%= full_title(yield(:title)) %></title>
    <%= csrf_meta_tags %>
    <%= stylesheet_link_tag    'application', media: 'all',
                               'data-turbolinks-track': 'reload' %>
    <%= javascript_include_tag 'application',
                               'data-turbolinks-track': 'reload' %>
  </head>
  <body>
    <%= yield %>
  </body>
</html>

<%= yield %>という部分で、home, aboutそれぞれのビューを可変します。
可変部は以下の通りです。

app/views/static_pages/home.html.erb
<% provide(:title, "Home") %>
<h1>Sample App</h1>
<p>
  This is the home page for the
  <a href="https://railstutorial.jp/">Ruby on Rails Tutorial</a>
  sample application.
</p>
app/views/static_pages/about.html.erb
<% provide(:title, "About") %>
<h1>About</h1>
<p>
  <a href="https://railstutorial.jp/">Ruby on Rails Tutorial</a>
  is a <a href="https://railstutorial.jp/#ebook">book</a> and
  <a href="https://railstutorial.jp/#screencast">screencast</a>
  to teach web development with
  <a href="http://rubyonrails.org/">Ruby on Rails</a>.
  This is the sample application for the tutorial.
</p>

タイトルを指定するには、以下のように書きます。

<% provide(:title, "〇〇") %>

こうすることで、application.html.erbにあるyield(:title)に文字列〇〇が代入されます。

Model

モデルは#5で使いますが、今のところは必要ありません。

#5まで不要

タイトルを動的に変更するヘルパーを作る

各ページでタイトルが変わるように、full_titleという名前でヘルパーメソッドを作成します。
ヘルパーとは、使い回しができるメソッドの置き場といったところです。
ルート以外のタイトルには先にページ名がくるよう定義します。

app/helpers/application_helper.rb
module ApplicationHelper

  def full_title(page_title = '')
    base_title = "Lantern Lantern" # 自分のアプリ名
    if page_title.empty?
      base_title
    else
      page_title + " | " + base_title
    end
  end
end

こうすることで、ビューのこの部分が理解できます。

<title><%= full_title(yield(:title)) %></title>
<% provide(:title, "〇〇") %>

full_titleの引数にyield(:title)、つまり〇〇が入ります。
空でなければ縦棒が入って、タイトルとして表示されます。

以上でMinitestからRSpecに変更するためのダミーページが完成しました。

RSpecを導入する

テストフレームワークで、より使われているのはMinitestではなくRSpecです。
ここでは企業が使っている母数を考え、RSpecを採用します。

それでは早速、導入します。
導入の手順は以下の通りです。

  • RSpecをインストールする
  • 必要なファイルと設定を追加する

RSpecをインストールする

Gemfileを使ってRSpecを導入します。
RailsでRSpecを使う際、rspec-railsというGemを使います。
#2以降、Gemをたくさん追加するので手順と用語を覚えます。

  • Gem → Ruby用のパッケージ管理
  • Gemfile → Gemを管理するファイル
  • Bundler → Gemの依存関係を整えるGem

Gemfileに以下を記述し、Bundlerを使ってインストールします。

Gemfile
group :development, :test do
+ gem 'rspec-rails'
end
shell
$ bundle install

必要なファイルと設定を追加する

次にファイルと設定を追加します。
ジェネレーターからRSpecのファイルを自動生成します。
設定の変更として、テストをドキュメント形式にします。

shell
$ rails g rspec:install
.rspec
--require spec_helper
--format documentation

これでRSpecが動作するようになりました。

参考になりました↓
RSpecとMinitest、使うならどっち?
RailsでRSpecテストを実行するまで

Rails TutorialのMinitestをRSpecで確認する

Rails Tutorial3章を進めると、初めてのテストにたどり着きます。
そのテストをMinitestからRSpecに書き直します。
以下は、MinitestとRSpecの差分です。
(一部改変)

static_pages_controller_test.rb(Minitest:Tutorial)
require 'test_helper'

class StaticPagesControllerTest < ActionDispatch::IntegrationTest

  test "should get home" do
    get static_pages_home_url
    assert_response :success
  end

  test "should get about" do
    get static_pages_about_url
    assert_response :success
  end
end
static_pages_controller_spec.rb(RSpec:ポートフォリオ)
require 'rails_helper'

RSpec.describe StaticPagesController, type: :controller do

  describe "GET #home" do
    it "returns http success" do
      get :home
      expect(response).to have_http_status(:success)
    end
  end

  describe "GET #about" do
    it "returns http success" do
      get :about
      expect(response).to have_http_status(:success)
    end
  end
end

ここで各テストとRSpecの対応を簡単に理解します。

  • 単体テスト → Model/Controller specなど
  • 統合テスト → Request spec
  • ブラウザテスト → System spec(Feature specは非推奨)

RSpecの理解はこちらを参考にします↓
使えるRSpec入門・その1「RSpecの基本的な構文や便利な機能を理解する」
Ruby on Rails のテストフレームワーク RSpec 事始め

次回以降からテストをRSpecで書くので、その都度覚えるよう心がけます。

ヘルパーテストを書く

full_titleヘルパーのテストを追加します。
Rails Tutorial 4.1.2 カスタムヘルパーでは、このテストをコントローラーテスト内に書いています。
しかしヘルパーに依存するテストをController Specに書くことは好まれません。
よってHelper specを生成します。

bash
$ rails g rspec:helper application
application_helper_spec.rb
require 'rails_helper'

RSpec.describe ApplicationHelper, type: :helper do
  
  describe "#full_title" do
    context "page_title is empty" do
      it "removes symbol" do
        expect(helper.full_title).to eq('Lantern Lantern')
      end
    end
    
    context "page_title is not empty" do
      it "returns title and application name where contains symbol" do
        expect(helper.full_title('hoge')).to eq('hoge | Lantern Lantern')
      end
    end
  end
end

参考になりました↓
Rails5でコントローラのテストをController specからRequest specに移行する
Ruby on Rails 5の上手な使い方 現場のエンジニアが教えるRailsアプリケーション開発の実践手法

ブラウザテストの雰囲気を掴む

ホームページのリンクを踏んだ際、ブラウザが反応するかのテストを確認します。
ブラウザテストにはSystem specを使います。

System specを使うには#4 System spec導入編セットアップが必要です。
今回はなんとなく雰囲気を掴むために、セットアップ後のコードを載せます。

spec/systems/site_layout_spec.rb
require 'rails_helper'

RSpec.describe "SiteLayouts", type: :system do
  
  describe "home layout" do
    it "returns title with 'Lantern Lantern'" do
      visit root_path
      expect(page).to have_title 'Lantern Lantern'
    end
  end
  
  describe "about layout" do
    it "returns title with 'About | Lantern Lantern'" do
      visit about_path
      expect(page).to have_title 'About | Lantern Lantern'
    end
  end
end

今はこんな感じか、と思うだけで十分です。
今回は以上です。


前回:#1 準備編
次回:#3 Bootstrap4, jQueryプラグイン導入編

13
9
0

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
13
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?