【Rails】静的ページのユニットページとリファクタリングについて

Rails tutorialの第3章を終えました。
その時の気づいたこととか備忘録です。
今回はユニットテストについて

railstutorial.jp

テスト対象コード

Railsユニットテストを行う際は
テストコードを書いたあと
$ rails testもしくは

$ rails t

で行えます。

静的ページのテスト

ここでは静的なページについてテストすることを見ます。

例: /app/view/hogeに静的なページ(home.html.erb)を作成し
そのページにTitle(Home | SampleApp)をつけるとします。

ユニットテスト

ここではテスト項目として
- アクセスできるか
- Titleがあっているか

をあげます。

上記を元にテストコードとしては下記が一つあげれます。
/test/controllers/Hoge_controller_test.rb

require 'test_helper'

class HogeControllerTest < ActionDispatch::IntegrationTest
  
  test "should get home" do
    get hoge_home_url
    assert_response :success
    assert_select "title", "Home | SampleApp"
  end
end
  • get hoge_home_url:GETリクエストをhomeアクションに発行。

  • assert_response :successはHTTP レスポンスは成功(200)が帰ってくればOK

  • assert_select "title", "Home | SampleApp"はここではtitleタグは"Home | SampleApp"


となります。
viewやコントローラの設定を行っていない場合やルーティングを行っていない場合
$ rails tを行っても当然ユニットテストは失敗します。

$ rails test
NameError: undefined local variable or method `hoge_home_url'
1 tests, 2 assertions, 2 failures, 0 errors, 0 skips

実装

次に、テストが通るように諸々設定してみます。

/app/views/hoge/home.html.erb

<!DOCTYPE html>
<html>
  <head>
    <title>Home | SampleApp</title>
  </head>
  <body>
    <h1>Sample App</h1>
    <p>
      This is the home page
    </p>
  </body>
</html>



/config/route.rb

Rails.application.routes.draw do
  get 'static_pages/home'
end



/app/controllers/hoge_controller.rb

class HogeController < ApplicationController
  def home
  end
end

こんな感じで書いてあげて、再び$rails tを行うと、
テストが通ってくれます。

$ rails test
1 tests, 2 assertions, 0 failures, 0 errors, 0 skips

複数ページのテスト

最後に同様の静的ページを複数作成し、
ついでにrootをルーティングした想定でテストを書きます。

/test/controllers/Hoge_controller_test.rb

  def setup
    @base_title = "SampleApp"
  end
  
  test "should get root" do
    get root_url
    assert_response :success
  end

  test "should get home" do
    get static_pages_home_url
    assert_response :success
    assert_select "title", "Home | #{@base_title}"
  end

  test "should get help" do
    get static_pages_help_url
    assert_response :success
    assert_select "title", "Help | #{@base_title}"
  end

ここでsetupメソッドは、各テスト実施前に実行を行うメソッドです。
Railsでは各テストの準備のためのメソッドとしてsetupメソッドを定義することで
他に何も設定しなくても勝手に実行できます。


また、root_urlでGETリクエストをroute.rb内のrootに定義したアクションに発行しにいきます

実装

このテストを通します。
新規作成:/app/views/hoge/help.html.erb

<!DOCTYPE html>
<html>
  <head>
    <title>Help | SampleApp</title>
  </head>
  <body>
    <h1>Sample App</h1>
    <p>
      This is the home page
    </p>
  </body>
</html>



/config/route.rb

Rails.application.routes.draw do
  get 'static_pages/home'
  #下記追加
  get 'static_pages/help'
  root 'static_pages#hello'
end



/app/controllers/hoge_controller.rb

class HogeController < ApplicationController
  def home
  end
 #下記追加
 def help
 end
end 

こんな感じにすれば通るかと思います。

$ rails test
3 tests, 5 assertions, 0 failures, 0 errors, 0 skips

リファクタリング

最後に、erbの重複している部分をlayouts/application_hepler.erbに逃がしてあげたら いい感じになると思います。

layouts/application_hepler.erb

<!DOCTYPE html>
<html>

<head>
  <title>
    <%= yield(:title) %> | Ruby on Rails Tutorial Sample App</title>
  <%= csrf_meta_tags %>
  <%= csp_meta_tag %>

  <%= stylesheet_link_tag    'application', media: 'all', 'data-turbolinks-track': 'reload' %>
  <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
</head>

<body>
  <%= yield %>
</body>

</html>


この際、viewに<% provide(:title, "Hoge") %>のように記述すると

application_hepler.erb<%= yield(:title) %> | "Hoge"
のように使用することができます。

(余談) application.html.erbはアプリケーションを新規作成した際に自動で作成されます
その際にCSSやJSについても自動で作成されます

またCSRFについては別記事にあります
onthebacksoftheflyer.hatenadiary.jp
CSPについては下記に詳しいです
qiita.com


あとはそれぞれのviewをいじってあげて、もう一度テストするといい感じかと思います

/app/views/hoge/help.html.erb

<% provide(:title, "Help") %>
<h1>Help</h1>
    <p>
      This is the home page
    </p>

/app/views/hoge/home.html.erb

<% provide(:title, "Home") %>
<h1>Help</h1>
    <p>
      This is the home page
    </p>

あとはテストを通したらいい感じです。

$ rails test
3 tests, 5 assertions, 0 failures, 0 errors, 0 skips

これを書いている人

業務でもユニットテストやったことない。
単体テストと言われたら、結果の画面キャプチャをエクセルで貼り付けてた人
このRailsチュートリアルが初めて、まともにテストコード書いて結果をコンソールで確認する人

参照

qiita.com