Railsチュートリアルの学習記録② ~3章 テスト~

はじめに

Railsチュートリアルの学習記録です。

※前回の記録

Railsチュートリアルの学習記録 ~1章・2章 scaffold活用~

第3章 ほぼ静的なページの作成

リンク

①プロジェクト作成

※プロジェクトは1から作り直していきます。

rails _5.1.6_ new rails_tutorial_app

この章ではテストを用いるのでminitestなど一部gemfileを編集。

source 'https://rubygems.org'

gem 'rails',        '5.1.6'
gem 'puma',         '3.9.1'
gem 'sass-rails',   '5.0.6'
gem 'uglifier',     '3.2.0'
gem 'coffee-rails', '4.2.2'
gem 'jquery-rails', '4.3.1'
gem 'turbolinks',   '5.0.1'
gem 'jbuilder',     '2.7.0'

group :development, :test do
  gem 'sqlite3', '1.3.13'
  gem 'byebug',  '9.0.6', platform: :mri
end

group :development do
  gem 'web-console',           '3.5.1'
  gem 'listen',                '3.1.5'
  gem 'spring',                '2.0.2'
  gem 'spring-watcher-listen', '2.0.1'
end

group :test do
  gem 'rails-controller-testing', '1.0.2'
  gem 'minitest',                 '5.10.3'
  gem 'minitest-reporters',       '1.1.14'
  gem 'guard',                    '2.16.2'
  gem 'guard-minitest',           '2.4.4'
end

group :production do
  gem 'pg' # バージョン指定しない
end

# Windows環境ではtzinfo-dataというgemを含める必要があります
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]

インストール

> bundle install --without production

You have requested:
minitest = 5.10.3

The bundle currently has minitest locked at 5.14.1.
Try running `bundle update minitest`

> bundle update

🙄本番環境のgemをインストールしないように注意ですね!!

上記でエラーになってしまったので、デフォルトのgemfileに以下のみ追記

group :test do
  gem 'rails-controller-testing', '1.0.2'
  gem 'minitest',                 '5.10.3'
  gem 'minitest-reporters',       '1.1.14'
  gem 'guard',                    '2.16.2'
  gem 'guard-minitest',           '2.4.4'
end

インストール

bundle update

マイグレート※何も処理されずに終わる

rails db:migrate
rails s # 普通に起動する

いったんここでプッシュしておきます。

git init
git add .
git commit -m"first commit"
git remote add ~~~
git push -u origin master

②ページ作成

applicationコントローラにhelloアクション追加

def hello
  render html: "hello world!"
end

routes.rbの設定

Rails.application.routes.draw do
  root 'application#hello'
end

※ここでブランチを作成&切り替えて作業

git checkout -b static-pages

③静的ページの作成

rails generate controller StaticPages home help

※上記でhomeアクションとhelpアクションが書かれた状態でstatic_pages_controllerが作成されます。

ここでプッシュ。

$ git add -A
$ git commit -m "Add a Static Pages controller"
$ git push -u origin static-pages

コントローラを間違った際の削除方法

rails destroy  controller StaticPages home help
rails destroy model User // これはモデルの場合。引数など不要。

🙄view関連のファイルも消えるのすごい。※routes.rbは変わらず。

マイグレーションを戻したい場合

rails db:rollback // 1つ元に戻したい場合
rails db:migrate VERSION=0 // 最初に戻したい場合

再度アクションを加えて作成。

rails g controller StaticPages home help about

ルーティングに自動追記、ビューも自動生成されているので、http://localhost:3000/static_pages/homeにアクセスして確認。

④テストしてみる

テスト駆動開発 (TDD) (テストの手法の1つ: 最初に「正しいコードがないと失敗するテスト」を書き、次に本編のコードを書いてそのテストがパスするようにする)

railsチュートリアルでのテストのガイドライン。

  • アプリケーションのコードよりも明らかにテストコードの方が短くシンプルになる (=簡単に書ける) のであれば、「先に」書く
  • 動作の仕様がまだ固まりきっていない場合、アプリケーションのコードを先に書き、期待する動作を「後で」書く
  • セキュリティが重要な課題またはセキュリティ周りのエラーが発生した場合、テストを「先に」書く
  • バグを見つけたら、そのバグを再現するテストを「先に」書き、回帰バグを防ぐ体制を整えてから修正に取りかかる
  • すぐにまた変更しそうなコード (HTML構造の細部など) に対するテストは「後で」書く
  • リファクタリングするときは「先に」テストを書く。特に、エラーを起こしそうなコードや止まってしまいそうなコードを集中的にテストする

最初にコントローラやモデルのテストを書き、続いて統合テスト (モデル/ビュー/コントローラにまたがる機能テスト) を書く

テストファイルの確認。

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

  test "should get about" do
    get static_pages_about_url
    assert_response :success
  end
end

上記はhomeとhelpに対応して書かれたテスト。

言葉で表すと「Homeページのテスト。GETリクエストをhomeアクションに対して発行 (=送信) せよ。そうすれば、リクエストに対するレスポンスは[成功]になるはず」となります。

テストの実行

> rails test
Run options: --seed 43947

# Running:

...

Finished in 3.347823s, 0.8961 runs/s, 0.8961 assertions/s.

3 runs, 3 assertions, 0 failures, 0 errors, 0 skips
16:36:09 - INFO - Run 'gem install win32console' to use color on Windows

※ここでテストにspringサーバーを使うとの記載。。。

⑤動的要素の追加※タイトル

テストを追加する。

※抜粋

assert_select "title", "About | Ruby on Rails Tutorial Sample App"

assert_selectメソッドは特定のHTMLタグが存在するかテストする。

※この時点だとエラーになる。

homeビュー側にタイトルを追加する。※他のビューも編集。コードは割愛。

<!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>

テストにsetupメソッド(テスト実行直前に実行される)を使う。

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 | #{@base_title}"
end

同じコードを繰り返すことはRubyの「DRY」(Don’t Repeat Yourself: 繰り返すべからず) という原則に反します。

provideメソッドを使い、タイトルをページごとに変更する。

application.html.erbの編集

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

home.html.erbも上記に伴い変更。※about,helpも同じく。

<% 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>

テスト

> rails test
3 runs, 6 assertions, 0 failures, 0 errors, 0 skips

🙄いちいちビューを閲覧する必要がないのでテスト書いておくと楽ですね。

ルーティングを変更

root 'static_pages#home'

テストにこれも追加

test "should get root" do
  get root_url
  assert_response :success
end

実行

> rails test
4 runs, 7 assertions, 0 failures, 0 errors, 0 skips

ここまででプッシュ!

$ git add -A
$ git commit -m "Finish static pages"
$ git checkout master
$ git merge static-pages
$ git push

※Guardによる自動テストの実装などはいったん割愛。

参考になった点

・Gitを使う場合は、masterブランチでずっと作業するのではなく、その都度トピックブランチを作成して作業するのがよい。

・Rubyがクラス名にキャメルケースを使う慣習

躓いた点

✅マイグレートできない

これは前回同様の問題ですね。

teratail:Railsチュートリアル2章 rails db:migrateのエラーRailsチュートリアル2章 rails db:migrate エラー

同様の問題で質問をされている方が2名おり、解決していないですね。

おそらくwindows特有の・・・ですね。

いったんステイします。

おわりに

いくつかプロジェクト作ってから気づいたけど、プロジェクト1つ当たりの容量が1MBいかないものもあったりして軽量で驚いた。おそらくグローバルにgemを管理してしまっているからだろうけど。。。ゆくゆくここ辺りもしっかり理解していきたい。

そしてLaravelでは全く実装できていなかったテストコードをさっそく書くことができた。
引き続きテストはどんどん書けるように勉強していきたい。

✅その他参考

git add -u と git add -A と git add . の違い

git add -ugit add -Aはレポジトリ内のどこで実行してもレポジトリ全体を処理するが、git add .はカレントディレクトリ以下のみを処理する。

備忘録

✅気になる点

テストにspringサーバーを使うと記載されているがgemfileでインストールしていない。

✅メモ

2章 Scaffoldの作成の際もデフォルトのgemfileを用いてアプリ制作したのでデフォルトのgemfileを以下に残します。

source 'https://rubygems.org'

git_source(:github) do |repo_name|
  repo_name = "#{repo_name}/#{repo_name}" unless repo_name.include?("/")
  "https://github.com/#{repo_name}.git"
end

gem 'rails', '~> 5.1.6'
gem 'sqlite3'
gem 'puma', '~> 3.7'
gem 'sass-rails', '~> 5.0'
gem 'uglifier', '>= 1.3.0'
gem 'coffee-rails', '~> 4.2'
gem 'turbolinks', '~> 5'
gem 'jbuilder', '~> 2.5'

group :development, :test do
  gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
  gem 'capybara', '~> 2.13'
  gem 'selenium-webdriver'
end

group :development do
  gem 'web-console', '>= 3.3.0'
end

gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]

 

gem 'jquery-rails', '4.3.1'

 

コメントを残す