[Rails]Minitestの基礎を詰め込む

# Minitestとは
Rails標準のテスティングフレームワークです。特に追加でgemを入れる必要もなく、使うことができます。
Minitestを使うことでルーティング、各コントローラ間のワークフロー、データベースとのやり取り、メソッドの挙動、ブラウザに返されるHTMLファイルの内容、等々、様々なものを簡単にテストすることができます。

RSpecしか使ったことない人が周りにたくさんいて(自分もですが、、笑)、とっつきにくい感じがしたので自分なりにわかりやすく解説します。。

##各フォルダの説明

| ディレクトリ構成 | 役割 |
|:-----------|------------:|
| test       |             |
| ├ controllers    | コントローラ・ビュー・ルーティングを纏めたテストを書く      |
| ├ fixtures       | テストのダミーデータを書く        |
| ├ helpers         | ビューヘルパーのテストを書く          |
| ├ integration       | コントローラ同士のやり取りのテスト(統合テスト)を書く       |
| ├ mailers    | メーラーのテストを書く     |
| ├ models    | モデルのテストを書く     |
| ├ system    　　　| システムテスト(jsなど、、)を書く     |
| application_system_test_case.rb    | システムテストのデフォルト設定を書く     |
| test_helper.rb    | テストのデフォルト設定を書く     |

## テストの書き方

```ruby

# test/test_helper.rbに記載されているデフォルト設定が読み込まれる
require 'test_helper'

class ArticleTest < ActiveSupport::TestCase
　 # 毎テスト実行前にして欲しい処理を書く
　 setup do
    @article = articles(:one)
  end 

  test "the truth" do　　# テストの命名
    assert true　　　　　 # テストの内容
  end
end
```

テストの内容の、基本的な文法は 「assert "期待する振る舞い","実装コードのメソッド","テストデータの値"」です。
実装コードのメソッドを使って、テストデータの値を入れてあげると、期待する振る舞いになるのか、テストをする

## assertを詳しく...!!

assert(アサーション)の直訳は「主張する」という意味で、たくさんの使い方があります。
assertメソッドの[msg]の箇所に文字列を渡すことで、テスト失敗時のエラーメッセージを指定することもできます。


|               　　　　 アサーション　　　　 |目的　　　　　　　　　　　                 |
|:--------------------------|----------------------:|
| assert(test, [msg])       |     式testの評価値は真であると主張　　　　　　　　　　        |
| assert_not(test, [msg])    | 式testの評価値は偽であると主張　    　　　　　　　　　  |
| assert_equal(expected, actual, [msg])	       | expected == actualの評価値は真であると主張　　　　        |
| assert_not_equal(expected, actual, [msg])         | expected == actualの評価値は偽であると主張　　　　          |
| assert_raises(exception1, exception2, ...) { block }       | 渡されたブロックから、引数に渡された例外のいずれかが発生すると主張　　　　　　　　　　　　　　　　　       |
| assert_operator(obj1, :演算子, [obj2], [msg])    | obj1.演算子(obj2)の評価値は真であると主張　　　　　     |
| flunk([msg])    | 必ず失敗すると主張　　　　　　　　　　　　　　　　     |

また、Rails固有のアサーションもあるのでよく使うもの3つを紹介します。

| 　　　　アサーション| 目的　　　　　　　　　　　　 |
|:-----------------|------------------------:|
| assert_nothing_raised { block } | 渡されたブロックで例外が発生しないことを確認します。| 
| assert_difference(expressions, difference = 1, message = nil, &block)    |      第一引数に渡した式の戻り値が、ブロックを実行することで、第二引数に渡した値だけ変化することを確認します                                                        |
| assert_no_difference(expressions, message = nil, &block)      | 第一引数に渡した式の戻り値が、ブロックを実行した後も変わらないことを確認します。        |


## 統合テスト
主に、複数のコントローラ同士のやり取りをテストすることを結合テストと呼びます。
コントローラー作成時にtest/controllers配下にテストファイルが生成されます。
新しいファイルを作成したい場合は以下のコマンドを打ち込みます。

```

$ bundle exec rails generate integration_test [テストファイル名]
```

## ダミーデータ作成方法

モデル作成時に、test/fixtures配下に.yml拡張子のfixtureファイルが生成されます。
fixtureファイルに記載されたデータはテスト実行前にテスト用のデータベースに導入(保存)することができます。

```hoge.yml

one:
  name: Hoge san
  email: hoge@hoge.com
```

また、アソシエーションも簡単に表現することができます。

```ruby

class Hoge < ApplicationRecord
  has_many: fuges
end

class Fuge < ApplicationRecord
  belongs_to: hoge
end

# test/fixtures/hoges.ymlの内容
one:
  name: aaaa

# test/fixtures/fuges.ymlの内容
two:
  email: fuge@fuge.com
  hoge: one 
```

## テスト実行方法

railsコマンドによって実行します。

```ruby

# すべてのテストを実行する(test/以下の)
$ rails test

# 特定フォルダ以下のすべてのテストを実行する
$ rails test test/models

# 複数のフォルダ以下のすべてのテストを実行する
$ rails test test/models test/jobs

# 特定のファイルの特定の行のテストを実行する
$ rails test test/models/user_test.rb:10
```

## 番外編
 spec スタイルでテストを書きたいときは minitest-rails を使おう!
minitest-rails を使う場合は test_helper.rb に以下を記述します。

```ruby

require 'minitest/rails'
```
また、自動で出来るテストファイルもspecスタイルにしたければ以下を追加する。

```config/application.rb

config.generators do |g|
  g.test_framework :minitest, spec: true
end
```

#終わりに

ここまで簡単ではありますが、説明してきました。
結局は慣れだとは思いますが、使っている現場も割とあるようなので使えるようにしていきましょう！

##参考
[Railsのテストの仕方](https://qiita.com/sei_sato/items/335a2dec9539307e65c6)

[Minitest でテスト、Rails のテスト (その1)](https://qiita.com/5t111111/items/5bb86896f85ac9cfc43f)