railsでのいろいろなテスト

>引用先
>[Railsチュートリアル](https://railstutorial.jp/)

#テストとは

言葉そのまんまで機能が正しく実装されたことを確認することです。
テストを書けばいざというときのセーフティネットにもなり、それ自体がアプリケーションのソースコードの「実行可能なドキュメント」にもなります。
テストが揃っていれば、バグを追うために余分な時間を使わずに済むため、正しく行えばむしろテストがないときよりも確実に開発速度がアップします。

#テストのメリット
1.機能停止に陥るような回帰バグを防止できる。
2.コードを安全にリファクタリング(改善)できる。
3.テストコードは、アプリケーションコードから見ればクライアントとして動作するので、アプリケーションの設計やシステムの他の部分とのインターフェイスを決めるときにも役に立つ。

#テストの実行
ターミナルにてrails generate controllerを実行した時点でテストファイルが作成されている。

```:ターミナル
# 例
$ rails generate controller StaticPages home help
```

↓

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

class StaticPagesControllerTest < ActionDispatch::IntegrationTest

  test "should get home" do    ←homeページのテスト
    get static_pages_home_url  ←GETリクエストをhomeアクションに対して送信
    assert_response :success   ←リクエストに対するレスポンスは［成功］になるはず
  end

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

↓

```:ターミナル
$ rails db:migrate     # システムによっては必要
$ rails test
2 tests, 2 assertions, 0 failures, 0 errors, 0 skips
```
0errorsのため問題なくコードが実装されている。

#わざとエラーを出してみる

aboutページを追加したと想定してコードを追加してみる。

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

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

テスト実行

```:ターミナル
$ rails test

NameError: undefined local variable or method `static_pages_about_url'
3 tests, 2 assertions, 0 failures, 1 errors, 0 skips
```

AboutページへのURLが見つからないとエラーメッセージ。
ルーティングファイルを修正してみる。

```ruby:config/routes.rb
Rails.application.routes.draw do
  get  'static_pages/home'
  get  'static_pages/help'
  get  'static_pages/about'   ←追加
  root 'application#hello'
end
```

テスト実行

```:ターミナル
$ rails test

AbstractController::ActionNotFound:
The action 'about' could not be found for StaticPagesController
```

StaticPagesコントローラにaboutアクションがないとエラーメッセージ。
aboutアクションを追加してみる。

```ruby:app/controllers/static_pages_controller.rb
class StaticPagesController < ApplicationController

  def home
  end

  def help
  end

  def about   ←追加
  end         ←追加
end
```

テスト実行

```:ターミナル
$ rails test
ActionController::UnknownFormat: StaticPagesController#about
is missing a template for this request format and variant.
```
テンプレート(ビュー)がないとエラーメッセージ。
下記コマンドか右クリックでビューファイルを作成。

```:ターミナル
$ touch app/views/static_pages/about.html.erb
```
テスト実行

```:ターミナル
$ rails test
3 tests, 3 assertions, 0 failures, 0 errors, 0 skips
```

0errorsになったのでテスト完了！！

テストが完了したのでコードをリファクタリングする
(今回はリファクタリングするコードがないため完了)

これを、「red ・ green ・ REFACTOR」のサイクルという。

***

#リンクのテスト

開発を進めて行く中でルーティングの設定をこのように行ったとする。

```
Rails.application.routes.draw do
  root 'static_pages#home'
  get  '/help',    to: 'static_pages#help'
  get  '/about',   to: 'static_pages#about'
  get  '/contact', to: 'static_pages#contact'
end
```
このようなルーティングを設定したとする。
この時にローカルサーバーのURLを毎回変えて確認するのは大変なのでテストを使って確認をしてみる。

```
$ rails generate integration_test site_layout
```

ターミナルでこのコードを打ち込むと
test/integration/site_layout_test.rb　のファイルが作成される。
このファイルを使ってテストコードを書いてみる。

```ruby:test/integration/site_layout_test.rb
require 'test_helper'

class SiteLayoutTest < ActionDispatch::IntegrationTest

  test "layout links" do
    get root_path
    assert_template 'static_pages/home'
    assert_select "a[href=?]", root_path, count: 2
    assert_select "a[href=?]", help_path
    assert_select "a[href=?]", about_path
    assert_select "a[href=?]", contact_path
  end
end
```

assert_select "a[href=?]", about_path   
　→　<a href="/about">...</a>このようなコードがあるかテストをする。

assert_select "a[href=?]", root_path, count: 2
　→　<a href="/">...</a>このようなコードが2つあるかテストをする。

###テストの実行
```
rails test:integration
```

##assert_select
assert_selectの指定の仕方の一部を紹介。

|Code|マッチするHTML |
|---|---|
|assert_select "div"|< div>foobar< /div>|
|assert_select "div", "foobar"|< div>foobar< /div>|
|assert_select "div.nav"|< div class="nav">foobar< /div>|
|assert_select "div#profile"|< div id="profile">foobar< /div>|
|assert_select "div[name=yo]"|< div name="yo">hey< /div>|
|assert_select "a[href=?]", '/', count: 1|< a href="/">foo< /a>|
|assert_select "a[href=?]", '/', text: "foo"|< a href="/">foo< /a>|

>引用先
>[Railsチュートリアル5章](https://railstutorial.jp/)

***