Railsチュートリアル 第3章 - ほぼ静的なページの実装を題材に、テスト駆動開発してみる

# 前提

[Railsチュートリアル 第3章 - rails createの裏側で何が行われているのか](https://qiita.com/rapidliner00/items/c53f38fb56fb6f3b74e4)の続きです。待ちに待ったテストの実装パートがやってきました。

# テストの実装事始め

Railsには、テストの実装を支援するための仕組みが実装されています。「`rails generate controller`を実行すると、コントローラテストも一緒に生成される」という動作もその一つです。前のエントリで作成下StaticPagesコントローラにも、現時点できちんとテストは作成されています。`test/controllers/static_pages_controller_test.rb`というファイルがそれです。

```ruby:test/controllers/static_pages_controller_test.rb
require 'test_helper'

class StaticPagesControllerTest < ActionDispatch::IntegrationTest
  test "should get home" do
    get static_pages_home_url
    assert_response :success
  end

  test "should get help" do
    get static_pages_help_url
    assert_response :success
  end

end
```

内容については、[Railsチュートリアルにおける説明](https://railstutorial.jp/chapters/static_pages?version=5.1#sec-our_first_test)を読んでもらいたいと思います。現時点では「テストは2つある」ということを認識しておきましょう。

いずれにせよ、「現時点でテストスイートを実行すると、問題なくパスする」という状態になっています。実際にテストを走らせてみましょう。開発環境で`rails test`というコマンドを実行するのです。

```:bash
# rails test
...略

# Running:

..

Finished in 1.759569s, 1.1366 runs/s, 1.1366 assertions/s.

2 runs, 2 assertions, 0 failures, 0 errors, 0 skips
```

「テストが2つ実行され、2つとも成功した」という意味のメッセージが表示されています。

# 初めてのテスト駆動開発

テスト駆動開発のサイクルは、以下のプロセスの積み重ねで進んでいきます。

1. 失敗するテストを最初に書く
2. アプリケーションのコードを書き、テストを成功させる
3. 必要ならばリファクタリングする

## 失敗するテストを書く

実際に、失敗するテストを最初に書いてみましょう。テーマは「Aboutページの実装」です。`test/controllers/static_pages_controller_test.rb`に、テストコードを書いていきます。前述のコードとの差分は以下のとおりです。

```diff:test/controllers/static_pages_controller_test.rb
class StaticPagesControllerTest < ActionDispatch::IntegrationTest
     assert_response :success
   end
 
+  test "should get about" do
+    get static_pages_about_url
+    assert_response :success
+  end
+
 end
```

## 見事テストが失敗する

開発環境上で、改めて`rails tast`を実行します。

```:bash
# rails test
...略

# Running:

.E.

Finished in 0.860237s, 3.4874 runs/s, 2.3249 assertions/s.

  1) Error:
StaticPagesControllerTest#test_should_get_about:
NameError: undefined local variable or method `static_pages_about_url' for #<StaticPagesControllerTest:0x000055649d2c1ee0>
    test/controllers/static_pages_controller_test.rb:15:in `block in <class:StaticPagesControllerTest>'

3 runs, 2 assertions, 0 failures, 1 errors, 0 skips
```

めでたく（？）テストが失敗しました。「1 errors」というのがその結果を示していますね。さあここから、「3 runs, 3 assertions」にしていきましょう。

## テストを成功させるまで

``undefined local variable or method `static_pages_about_url'...略``というエラーメッセージが表示されていますね。「url」という文字列があるということは、`config/routes.rb`を変更するのでしょう。というわけで、以下の変更を加えていきます。

```diff:config/routes.rb
diff --git a/config/routes.rb b/config/routes.rb
index 56f06f7..c9da274 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -3,5 +3,7 @@ Rails.application.routes.draw do
 
   get 'static_pages/help'
 
+  get 'static_pages/about'
+
   root 'application#hello'
 end
```

開発環境にて、再び`rails test`を実行してみます。

```:bash
# rails test
...略

# Running:

E..

Finished in 1.112838s, 2.6958 runs/s, 1.7972 assertions/s.

  1) Error:
StaticPagesControllerTest#test_should_get_about:
AbstractController::ActionNotFound: The action 'about' could not be found for StaticPagesController
    test/controllers/static_pages_controller_test.rb:15:in `block in <class:StaticPagesControllerTest>'

3 runs, 2 assertions, 0 failures, 1 errors, 0 skips
```

やはりテストは失敗しますね。

ただ、エラーメッセージの中身には変化がありました。`The action 'about' could not be found for StaticPagesController`というやつです。「StaticPagesController」という文字列があるということは、`app/controllers/static_pages_controller.rb`を変更するのでしょう。というわけで、以下の変更を加えていきます。

```diff:app/controllers/static_pages_controller.rb
diff --git a/app/controllers/static_pages_controller.rb b/app/controllers/static_pages_controller.rb
index c76b925..19f79a9 100644
--- a/app/controllers/static_pages_controller.rb
+++ b/app/controllers/static_pages_controller.rb
@@ -4,4 +4,7 @@ class StaticPagesController < ApplicationController
 
   def help
   end
+
+  def about
+  end
 end
```

開発環境にて、再び`rails test`を実行してみます。

```:bash
# rails test
...略

# Running:

E..

Finished in 1.832907s, 1.6367 runs/s, 1.0912 assertions/s.

  1) Error:
StaticPagesControllerTest#test_should_get_about:
ActionController::UnknownFormat: StaticPagesController#about is missing a template for this request format and variant.

request.formats: ["text/html"]
request.variant: []

NOTE! For XHR/Ajax or API requests, this action would normally respond with 204 No Content: an empty white screen. Since you're loading it in a web browser, we assume that you expected to actually render a template, not nothing, so we're showing an error to be extra-clear. If you expect 204 No Content, carry on. That's what you'll get from an XHR or API request. Give it a shot.
    test/controllers/static_pages_controller_test.rb:15:in `block in <class:StaticPagesControllerTest>'

3 runs, 2 assertions, 0 failures, 1 errors, 0 skips
```

また失敗です。

ただ、またエラーメッセージが変わりましたね。今度は`ActionController::UnknownFormat: StaticPagesController#about is missing a template for this request format and variant.`というメッセージになっています。

「missing a template」というのは、「コントローラが要求するビューがない」という趣旨のメッセージです。今回の場合であれば、「`app/views/static_pages/about.html.erb`」があればOKなはずです。早速当該ファイルを作成しましょう。Railsチュートリアル本文に倣い、内容は以下の通りとします。

```erb:app/views/static_pages/about.html.erb
<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>
```

```:bash
# rails test
...略

# Running:

...

Finished in 0.719320s, 4.1706 runs/s, 4.1706 assertions/s.

3 runs, 3 assertions, 0 failures, 0 errors, 0 skips
```

ついにテストが成功しました！

この時点でRailsのdevelopmentサーバーを起動し、`/static_pages/about`をWebブラウザで表示すると、結果は以下のとおりになりました。

<img width="1132" alt="スクリーンショット 2019-08-14 15.36.02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/323778/55ba6469-6469-8d0d-3175-d998293afdfb.png">

# リファクタリングしてみよう

[Railsチュートリアル本文](https://railstutorial.jp/chapters/static_pages?version=5.1#sec-our_first_test)においては、ここで「Home、Help、Aboutそれぞれのページを編集し、各ページ異なるタイトルを表示する」という機能追加を行います。そのときの具体的な実装手順として、以下の手順で行うことが示されています。

1. ページタイトルの簡単なテストを書く(RED)
2. 3つのページにタイトルを追加する(GREEN)
3. レイアウトファイルを活用してコードの重複を解決する(REFACTOR)

「テストとリファクタリングという一連の手順を実際にやってみよう」ということですね。「テストとリファクタリング」という考え方は大変重要ですし、実際に手を動かすことは覚えることへの早道なので、その手順をなぞってみることにします。

まず、この後の手順を進めるため、ソースコード内にある既存レイアウトファイルを一旦リネームします。

```:zsh
>>> pwd
~/docker/rails_tutorial_test/sample_app

>>> mv app/views/layouts/application.html.erb layout_file
```

## ページタイトルの追加 - テストを成功させるまで

続いて、テストを以下のように書き換えます。

```diff:test/controllers/static_pages_controller_test.rb
class StaticPagesControllerTest < ActionDispatch::IntegrationTest
   test "should get home" do
     get static_pages_home_url
     assert_response :success
+    assert_select "title", "Home | Ruby on Rails Tutorial Sample App"
   end
 
   test "should get help" do
     get static_pages_help_url
     assert_response :success
+    assert_select "title", "Help | Ruby on Rails Tutorial Sample App"
   end
 
   test "should get about" do
     get static_pages_about_url
     assert_response :success
+    assert_select "title", "About | Ruby on Rails Tutorial Sample App"
   end
 
 end
```

この時点における`rails test`の結果は以下のとおりです。

```:bash
# rails test
...略

# Running:

FFF

Finished in 0.573597s, 5.2302 runs/s, 10.4603 assertions/s.

  1) Failure:
StaticPagesControllerTest#test_should_get_home [/var/www/sample_app/test/controllers/static_pages_controller_test.rb:7]:
Expected at least 1 element matching "title", found 0..
Expected 0 to be >= 1.

  2) Failure:
StaticPagesControllerTest#test_should_get_about [/var/www/sample_app/test/controllers/static_pages_controller_test.rb:19]:
Expected at least 1 element matching "title", found 0..
Expected 0 to be >= 1.

  3) Failure:
StaticPagesControllerTest#test_should_get_help [/var/www/sample_app/test/controllers/static_pages_controller_test.rb:13]:
Expected at least 1 element matching "title", found 0..
Expected 0 to be >= 1.

3 runs, 6 assertions, 3 failures, 0 errors, 0 skips
```
失敗が3つ出ていますね。「Home、About、Helpそれぞれのビューにおいて、title要素が存在しない」という趣旨のメッセージが書かれています。

Home、About、Helpそれぞれのビューを以下のように書き換えます。

```diff:app/views/static_pages/home.html.erb
-<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>
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>Home | Ruby on Rails Tutorial Sample App</title>
+  </head>
+  <body>
+    <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>
+  </body>
+</html>
```

```diff:app/views/static_pages/help.html.erb
-<h1>Help</h1>
-<p>
-  Get help on the Ruby on Rails Tutorial at the
-  <a href="https://railstutorial.jp/help">Rails Tutorial help page</a>.
-  To get help on this sample app, see the
-  <a href="https://railstutorial.jp/#ebook"><em>Ruby on Rails Tutorial</em>
-  book</a>.
-</p>
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>Help | Ruby on Rails Tutorial Sample App</title>
+  </head>
+  <body>
+    <h1>Help</h1>
+    <p>  Get help on the Ruby on Rails Tutorial at the
+      <a href="https://railstutorial.jp/help">Rails Tutorial help
+      page</a>.
+      To get help on this sample app, see the
+      <a href="https://railstutorial.jp/#ebook">
+      <em>Ruby on Rails Tutorial</em> book</a>.
+    </p>
+  </body>
+</html>
```

```diff:app/views/static_pages/about.html.erb
-<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>
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>About | Ruby on Rails Tutorial Sample App</title>
+  </head>
+  <body>
+    <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>
+  </body>
+</html>
```

再び`rails test`を実行すると、今度はテストが成功します。

```:bash
# rails test
...略

# Running:

...

Finished in 0.557244s, 5.3836 runs/s, 10.7673 assertions/s.

3 runs, 6 assertions, 0 failures, 0 errors, 0 skips
```

## 演習 - テストケースの追加と、テストが成功することの確認

[Railsチュートリアル本文](https://railstutorial.jp/chapters/static_pages?version=5.1#sec-our_first_test)によれば、演習の内容は以下のとおりです。

> StaticPagesコントローラのテスト (リスト 3.24) には、いくつか繰り返しがあったことにお気づきでしょうか? 特に「Ruby on Rails Tutorial Sample App」という基本タイトルは、各テストで毎回同じ内容を書いてしまっています。そこで、setupという特別なメソッド (各テストが実行される直前で実行されるメソッド) を使って、この問題を解決したいと思います。まずは、リスト 3.30のテストが green になることを確認してみてください (リスト 3.30では、2.2.2で少し触れたインスタンス変数や文字列の式展開というテクニックを使っています。それぞれ4.4.5と4.2.2で詳しく解説するので、今はわからなくても問題ありません)。 

まず、`test/controllers/static_pages_controller_test.rb`を書き換えます。

```diff:test/controllers/static_pages_controller_test.rb
 require 'test_helper'
 
 class StaticPagesControllerTest < ActionDispatch::IntegrationTest
+
+  def setup
+    @base_title = "Ruby on Rails Tutorial Sample App"
+  end
+
   test "should get home" do
     get static_pages_home_url
     assert_response :success
-    assert_select "title", "Home | Ruby on Rails Tutorial Sample App"
+    assert_select "title", "Home | #{@base_title}"
   end
 
   test "should get help" do
     get static_pages_help_url
     assert_response :success
-    assert_select "title", "Help | Ruby on Rails Tutorial Sample App"
+    assert_select "title", "Help | #{@base_title}"
   end
 
   test "should get about" do
     get static_pages_about_url
     assert_response :success
-    assert_select "title", "About | Ruby on Rails Tutorial Sample App"
+    assert_select "title", "About | #{@base_title}"
   end
 
 end
```

再び`rails test`を実行します。

```:bash
# rails test
...略

# Running:

...

Finished in 0.487921s, 6.1485 runs/s, 12.2971 assertions/s.

3 runs, 6 assertions, 0 failures, 0 errors, 0 skips
```

Railsチュートリアル本文記載のとおり、テストが成功することが確認できました。

## ERBを使って、ページタイトルの一部を変数で与えるようにしてみる

今度は、「Home、Help、Aboutそれぞれのビューを編集し、ページタイトルの一部を変数で与えるようにする」という機能を実装してみます。各ビューの内容の差分は以下のとおりです。

```diff:app/views/static_pages/home.html.erb
+<% provide(:title, "Home") %>
 <!DOCTYPE html>
 <html>
   <head>
-    <title>Home | Ruby on Rails Tutorial Sample App</title>
+    <title><%= yield(:title) %> | Ruby on Rails Tutorial Sample App</title>
   </head>
   <body>
     <h1>Sample App</h1>
```

```diff:app/views/static_pages/help.html.erb
+<% provide(:title, "Help") %>
 <!DOCTYPE html>
 <html>
   <head>
-    <title>Help | Ruby on Rails Tutorial Sample App</title>
+    <title><%= yield(:title) %> | Ruby on Rails Tutorial Sample App</title>
   </head>
   <body>
     <h1>Help</h1>
```

```diff:app/views/static_pages/about.html.erb
+<% provide(:title, "About") %>
 <!DOCTYPE html>
 <html>
   <head>
-    <title>About | Ruby on Rails Tutorial Sample App</title>
+    <title><%= yield(:title) %> | Ruby on Rails Tutorial Sample App</title>
   </head>
   <body>
     <h1>About</h1>
```

`rails test`を実行します。

```:bash
# rails test
...略

# Running:

...

Finished in 0.694081s, 4.3223 runs/s, 8.6445 assertions/s.

3 runs, 6 assertions, 0 failures, 0 errors, 0 skips
```

テストも無事成功していますね。

## リファクタリング - HTMLの重複した構造をDRYにする

まず、項目「リファクタリングしてみよう」の冒頭で退避させていた`app/views/layouts/application.html.erb`の内容を元に戻します。

```:zsh
>>> pwd
~/docker/rails_tutorial_test/sample_app

>>> mv layout_file app/views/layouts/application.html.erb
```

`app/views/layouts/application.html.erb`を以下の内容で書き換えます。

```erb:app/views/layouts/application.html.erb
<!DOCTYPE html>
<html>
  <head>
    <title><%= yield(:title) %> | Ruby on Rails Tutorial Sample App</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>
```

以降、Sampleアプリは`app/views/layouts/application.html.erb`でHome、Help、AboutそれぞれのビューのHTML構造を定義する動作になります。各ビューに`body`の内容以外は不要になるので、不要な部分は削除します。差分は以下のとおりです。

```diff:app/views/static_pages/home.html.erb
 <% provide(:title, "Home") %>
-<!DOCTYPE html>
-<html>
-  <head>
-    <title><%= yield(:title) %> | Ruby on Rails Tutorial Sample App</title>
-  </head>
-  <body>
-    <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>
-  </body>
-</html>
+<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>
```

```diff:app/views/static_pages/help.html.erb
 <% provide(:title, "Help") %>
-<!DOCTYPE html>
-<html>
-  <head>
-    <title><%= yield(:title) %> | Ruby on Rails Tutorial Sample App</title>
-  </head>
-  <body>
-    <h1>Help</h1>
-    <p>  Get help on the Ruby on Rails Tutorial at the
-      <a href="https://railstutorial.jp/help">Rails Tutorial help
-      page</a>.
-      To get help on this sample app, see the
-      <a href="https://railstutorial.jp/#ebook">
-      <em>Ruby on Rails Tutorial</em> book</a>.
-    </p>
-  </body>
-</html>
+<h1>Help</h1>
+<p>  Get help on the Ruby on Rails Tutorial at the
+  <a href="https://railstutorial.jp/help">Rails Tutorial help section</a>.
+  To get help on this sample app, see the
+  <a href="https://railstutorial.jp/#ebook"><em>Ruby on Rails Tutorial</em>
+  book</a>.
+</p>
```

```diff:app/views/static_pages/about.html.erb
 <% provide(:title, "About") %>
-<!DOCTYPE html>
-<html>
-  <head>
-    <title><%= yield(:title) %> | Ruby on Rails Tutorial Sample App</title>
-  </head>
-  <body>
-    <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>
-  </body>
-</html>
+<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>
```

テストが成功することを確認するのも忘れてはいけません。

```
# rails test
...略

# Running:

...

Finished in 0.651065s, 4.6078 runs/s, 9.2157 assertions/s.

3 runs, 6 assertions, 0 failures, 0 errors, 0 skips
```

ソースコードに対する変更をGitリポジトリにコミットするのも忘れずに。

```:zsh
>>> git add -A
>>> git commit -am "Add application.html.erb"
>>> git push
```

# 演習 - サンプルアプリケーションにContact (問い合わせ先) ページを作成してみる

[Railsチュートリアル本文](https://railstutorial.jp/chapters/static_pages?version=5.1#sec-our_first_test)によれば、演習の内容は以下のとおりです。

> サンプルアプリケーションにContact (問い合わせ先) ページを作成してください16 (ヒント: まずはリスト 3.15を参考にして、/static_pages/contactというURLのページに「Contact | Ruby on Rails Tutorial Sample App」というタイトルが存在するかどうかを確認するテストを最初に作成しましょう。次に、3.3.3でAboutページを作ったときのと同じように、Contactページにもリスト 3.40のコンテンツを表示してみましょう。)。 

まず、`test/controllers/static_pages_controller_test.rb`に、Contactビューに対するテストコードを追加します。

```diff:test/controllers/static_pages_controller_test.rb
 class StaticPagesControllerTest < ActionDispatch::IntegrationTest
     assert_select "title", "About | #{@base_title}"
   end
 
+  test "should get contact" do
+    get static_pages_contact_url
+    assert_response :success
+    assert_select "title", "Contact | #{@base_title}"
+  end
+
 end
```

この時点でテストを実行します。

```:bash
# rails test
...略

# Running:

.E..

Finished in 1.085848s, 3.6838 runs/s, 5.5256 assertions/s.

  1) Error:
StaticPagesControllerTest#test_should_get_contact:
NameError: undefined local variable or method `static_pages_contact_url' for #<StaticPagesControllerTest:0x000055b6c4f0ba88>
    test/controllers/static_pages_controller_test.rb:28:in `block in <class:StaticPagesControllerTest>'

4 runs, 6 assertions, 0 failures, 1 errors, 0 skips
```

当然テストは失敗します。``undefined local variable or method `static_pages_contact_url'``というメッセージがポイントですね。`url`とあるだけに、`config/routes.rb`に`static_pages/contact`へのルーティングが設定されていないことが問題のようです。早速`config/routes.rb`を書き換えます。

```diff:config/routes.rb
 
   get 'static_pages/about'
 
+  get 'static_pages/contact'
+
   root 'application#hello'
 end
```

再びテストを実行します。

```:bash
# rails test
...略

# Running:

.E..

Finished in 1.048572s, 3.8147 runs/s, 5.7221 assertions/s.

  1) Error:
StaticPagesControllerTest#test_should_get_contact:
AbstractController::ActionNotFound: The action 'contact' could not be found for StaticPagesController
    test/controllers/static_pages_controller_test.rb:28:in `block in <class:StaticPagesControllerTest>'

4 runs, 6 assertions, 0 failures, 1 errors, 0 skips
```

失敗しましたが、メッセージの内容が変わっています。`The action 'contact' could not be found for StaticPagesController`とありますね。StaticPagesコントローラに`contact`というアクションが存在しないことが原因のようです。`app/controllers/static_pages_controller.rb`に、`StaticPages#contact`というアクションの定義を追加します。

```diff:app/controllers/static_pages_controller.rb
class StaticPagesController < ApplicationController
 
   def about
   end
+
+  def contact
+  end
 end
```

再びテストを実行します。

```:bash
# rails test
...略

# Running:

..E.

Finished in 1.480814s, 2.7012 runs/s, 4.0518 assertions/s.

  1) Error:
StaticPagesControllerTest#test_should_get_contact:
ActionController::UnknownFormat: StaticPagesController#contact is missing a template for this request format and variant.

request.formats: ["text/html"]
request.variant: []

...略

4 runs, 6 assertions, 0 failures, 1 errors, 0 skips
```

また失敗しましたが、またメッセージの内容が変わっています。`StaticPagesController#contact is missing a template for this request format and variant.`というメッセージですね。内容が定義された`app/views/static_pages/contact.html.erb`が必要になる、ということなのでしょう。早速当該ファイルを作成し、内容を定義します。

```:zsh
>>> pwd
~/docker/rails_tutorial_test/sample_app

>>> touch app/views/static_pages/contact.html.erb
```

```erb:app/views/static_pages/contact.html.erb
<% provide(:title, "Contact") %>
<h1>Contact</h1>
<p>
  Contact the Ruby on Rails Tutorial about the sample app at the
  <a href="https://railstutorial.jp/contact">contact page</a>.
</p>
```

再びテストを実行します。

```:bash
# rails test
Running via Spring preloader in process 473
/var/www/sample_app/db/schema.rb doesn't exist yet. Run `rails db:migrate` to create it, then try again. If you do not intend to use a database, you should instead alter /var/www/sample_app/config/application.rb to limit the frameworks that will be loaded.
Run options: --seed 32838

# Running:

....

Finished in 0.908276s, 4.4039 runs/s, 8.8079 assertions/s.

4 runs, 8 assertions, 0 failures, 0 errors, 0 skips
```

テストが成功しました。Webブラウザで/static_pages/contactを表示した結果は以下のとおりです。

<img width="879" alt="スクリーンショット 2019-08-14 22.19.21.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/323778/d38333b0-d73b-1f20-b998-e1fdc46e0e26.png">

# ルーティングの設定

`config/routes.rb`を書き換え、/にアクセスした際に/static_pages/homeが表示されるようにします。

```diff:config/routes.rb
 Rails.application.routes.draw do
+  root 'static_pages#home'
   get 'static_pages/home'
-
   get 'static_pages/help'
-
   get 'static_pages/about'
-
   get 'static_pages/contact'
-
-  root 'application#hello'
 end
```

この時点でWebブラウザで/を表示すると、結果は以下のとおりになります。

<img width="879" alt="スクリーンショット 2019-08-14 22.39.49.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/323778/d0132479-fe6e-87f3-787e-bc49a31acd32.png">

# 演習 - rootルーティングに対するテスト

## 1.rootルーティングのテストを書いてみてください。

テストコードは以下のとおりです。

```diff:test/controllers/static_pages_controller_test.rb
class StaticPagesControllerTest < ActionDispatch::IntegrationTest
     @base_title = "Ruby on Rails Tutorial Sample App"
   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

```

テストを実行します。

```
# rails test
...略

# Running:

.....

Finished in 1.082391s, 4.6194 runs/s, 8.3149 assertions/s.

5 runs, 9 assertions, 0 failures, 0 errors, 0 skips
```

テストは成功しました。

## 2. rootルーティングをコメントアウトして見て、 redになるかどうか確かめてみましょう。

```diff:config/routes.rb
 Rails.application.routes.draw do
-  root 'static_pages#home'
+  #root 'static_pages#home'
   get 'static_pages/home'
   get 'static_pages/help'
   get 'static_pages/about'
   get 'static_pages/contact'
 end
```

```
# rails test
...略

# Running:

..E..

Finished in 0.862515s, 5.7970 runs/s, 9.2752 assertions/s.

  1) Error:
StaticPagesControllerTest#test_should_get_root:
NameError: undefined local variable or method `root_url' for #<StaticPagesControllerTest:0x0000556f1b7f69c8>
    test/controllers/static_pages_controller_test.rb:10:in `block in <class:StaticPagesControllerTest>'

5 runs, 8 assertions, 0 failures, 1 errors, 0 skips
```

テストは失敗しました。``undefined local variable or method `root_url' ...略 `block in <class:StaticPagesControllerTest>'``というメッセージが表示されていますね。「`root`へのルーティングが定義されていない」という趣旨のエラーメッセージなので、確かに先ほどrootルーティングをコメントアウトしたのが原因のようです。

演習が終わったら、rootルーティングのコメントアウトを元に戻すのを忘れずに。

# 最後に、本番環境へのデプロイ

## まず、ブランチ`static-pages`の内容を`master`にマージする

```:zsh
>>> git checkout master
>>> git merge static-pages
>>> git push
```

以上のコマンドを順に実行します。以下の操作が順に実行されます。

1. 作業対象のブランチを`master`に変更する
2. ブランチ`static-pages`に適用された変更を、現在の作業対象のブランチにマージする
3. 現在の作業対象のブランチに適用された変更をGitHubにプッシュする

## ローカルの`master`に適用された変更をHerokuにプッシュする

ここまで実行し、現在の作業対象のブランチが`master`であることを確認したら、いよいよHerokuにここまでの内容をデプロイします。

```:zsh
>>> git branch
* master
  static-pages

>>> git push heroku
Total 0 (delta 0), reused 0 (delta 0)
...略
To https://git.heroku.com/warm-woodland-62915.git
   ffe2338..2ffdc50  master -> master
```

Herokuで/にアクセスしてみます。

<img width="879" alt="スクリーンショット 2019-08-16 9.43.30.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/323778/66b7fcd2-ee21-03d3-43ea-61b86f1e3138.png">

/homeの内容が表示されました。

## 余談…リモートブランチを削除する

間違ってブランチ`static-pages`をHerokuにプッシュしてしまったという場合は、当該リモートブランチを削除しておきましょう。「ローカルブランチを指定せずにリモートブランチにプッシュする」という操作を行うことによって、リモートブランチを削除することができます。

```:zsh
>>> git push heroku :static-pages
remote: Pushed to non-master branch, skipping build.
To https://git.heroku.com/warm-woodland-62915.git
 - [deleted]         static-pages
```