[作成中]RSpecについて初学者段階のメモ

※間違いなどございましたらご指摘いただけると幸いです
※随時更新予定

# 概要
以下、https://semaphoreci.com/community/tutorials/getting-started-with-rspec より引用
 > RSpec is a testing tool for Ruby, created for behavior-driven development (BDD). It is the most frequently used testing library for Ruby in production applications.
 「RSpec は、ビヘイビア駆動開発 (BDD) 用に作成された Ruby のテスト ツールです。本番アプリケーションで最も頻繁に使用される Ruby のテスト ライブラリです。」(Google翻訳)

- `RSpec`はRailsアプリケーションの開発で利用するテストツール
    - Railsに最初から搭載されている"minitest"というテストツールも存在するが、RSpecが実質デファクトスタンダードとされている
        - それだけ"minitest"よりも使用されているのが分かる

## "minitest" v.s. "RSpec"
Q.どっちも同じテストツールなら何が違うの？
<INS>A.minitestはシンプルで学習しやすい。<br>　RSpecは高度な機能が提供されており豊富な表現が可能。<INS>

色々と参考にしましたが以下の通りにまとめられます

### "minitest"
- **メリット**
    - 構文がシンプル → 故に学習もしやすい
    - Railsチュートリアル、Railsガイドではこちらが使用されている → 故に学習もしやすい
    - 公式がサポートしてくれている安心感
    - 軽量で小規模なプロジェクトには最適
- **デメリット**
    - 高度な機能が不十分
    - 複雑な構文は書けない（拡張性が不十分と感じるかも）
### "RSpec"
- **メリット**
    - テストの説明を「会話のような概念を表現できる」ため
    - デファクトスタンダードと呼ばれるぐらいにシェアが高い
    - ドキュメントも豊富と言われている
    - 機能の拡張性もあり柔軟 → 大規模なプロジェクトに使える
- **デメリット**
    - minitestよりは学習コストが高い
    - 単純なテストに対しても「会話のような概念を表現」するため冗長に感じる場合もある

# RSpecによるテスト
[ドキュメント](https://rspec.info/documentation/3.7/rspec-rails/)を参考にすると以下のように「～specs」というのが幾つか確認できます。
- これらは様々の処理についてテストをする際に利用します
    - 例えば"Model Specs"はアプリケーションの Model が正しい振る舞いを行っているかテストする際に用いる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3518714/f720ecbb-0ea4-b1e7-4485-48be75aa83bc.png)

## 基本構文
RSpecではテストコードを組織化して書くために`describe`、`context`、`it`というブロックを使用
- このキーワードを使用して「何のどこの処理のテストなのか」を明記してテストケースを作っていく
    - 以下のサンプルコードのようにテストケースをグループ分けしていく
        - `describe`、`context`、`it` を用いてネストで（親子関係を持たせて）何のテストなのかを明示していく

（サンプル１）
> ``` 
> RSpec.describe Order do
>   context "with no items" do
>     it "behaves one way" do
>       # ...
>     end
>   end
>   context "with one item" do
>     it "behaves another way" do
>       # ...
>     end
>   end
> end 
> ```
> 引用 : https://rspec.info/documentation/3.13/rspec-core/#basic-structure:~:text=%E3%82%8C%E3%81%BE%E3%81%99%E3%80%82-,%E3%83%8D%E3%82%B9%E3%83%88%E3%81%95%E3%82%8C%E3%81%9F%E3%82%B0%E3%83%AB%E3%83%BC%E3%83%97,-describe%E3%81%BE%E3%81%9F%E3%81%AF%E3%83%A1%E3%82%BD%E3%83%83%E3%83%89

（サンプル２）
> ``` 
> RSpec.describe 'Post' do           #
>   context 'before publication' do  # (almost) plain English
>     it 'cannot have comments' do   #
>       expect { Post.create.comments.create! }.to raise_error(ActiveRecord::RecordInvalid)  # test code
>     end
>   end
> end
> ```
> 引用 : https://rspec.toolboxforweb.xyz/ja/docs/rspec-rails#rspec-dsl%E3%81%AE%E5%9F%BA%E6%9C%AC%E3%82%B9%E3%83%9A%E3%83%83%E3%82%AF%E3%81%AE%E6%9B%B8%E3%81%8D%E6%96%B9

### ブロック
以下のキーワードを用いて「コードがどのように動作するかをまとめるため」にテストケースをグループ化していく。
- **[describe](https://rubydoc.info/gems/rspec-core/RSpec/Core/ExampleGroup.description)**
    - テストケースのグループの説明
        - この`describe`が最上位のグループ親になる
        - 「何のシステム・機能をテスト対象としているグループなのか」が載っている
- **[context](https://rubydoc.info/gems/rspec-core/RSpec/Core/ExampleGroup#include_context-class_method)**
    - この`context`が`describe`の子に相当する<br>⇒このキーワードを用いて親の`describe`直下にネストを作る
    - `describe`は漠然と「機能」についてのグループ分けとしたら、`context`は「その機能の何の条件・状況かのテストなのか」を明記する
- **[it](https://rubydoc.info/gems/rspec-core/RSpec/Core/ExampleGroup#it-class_method)**
    - 最も最下位の子に相当する
    - `it`は上2つとは異なり詳細にテストケースの説明を載せる


:::note warn
（サンプル２）のドキュメントより、
> RSpecでは、アプリケーションの振る舞いをほぼプレーンな英語で記述し、その後にテストコードで再度記述します。例えば、次のようになります。

とありますが、 `describe`、`context`、`it` に日本語で記述しているケースが散見されるため英語である必要は無さそう
:::

### 検証メソッド
先述のブロックでテストケースを検証メソッドで具体的にどういった結果が期待されているかをテストする
- `expect().to` の構文で具体的な値を検証する
- `expect().to` に続いて'マッチャー'というキーワードを付属させてテスト結果を判定する
    - キーワードは複数存在する → [Built-in matchers](https://rspec.toolboxforweb.xyz/docs/rspec-expectations/#built-in-matchers)
> ```:サンプルコード
> expect(account.balance).to eq(Money.new(37.42, :USD))
> ```
> 引用 : [RSpec Expectations](https://rspec.toolboxforweb.xyz/docs/rspec-expectations/#basic-usage:~:text=Also%20see-,RSpec%20Expectations,-RSpec%3A%3AExpectations%20lets)





---
### 参考書籍・サイト・記事

[記事全体]

https://www.rubydoc.info/gems/capybara/index

https://semaphoreci.com/community/tutorials/getting-started-with-rspec

https://gihyo.jp/book/2020/978-4-297-11462-6

https://rspec.info/documentation/

https://qiita.com/iijima-naoya-45b/items/b4fe4e8b86db5618be6c#rspec%E3%81%A8%E3%81%AF

https://qiita.com/mine_slj/items/e9d5a6a30b5343d2b64c#%E3%83%86%E3%82%B9%E3%83%88%E3%82%B1%E3%83%BC%E3%82%B9%E3%81%AE%E4%BE%8B

[概要]

https://medium.com/@salujabhavesh/rspec-vs-minitest-for-ruby-on-rails-testing-b08fa27d6cf6

[RSpecによるテスト]

https://rspec.info/documentation/3.7/rspec-rails/

https://rspec.toolboxforweb.xyz/ja/docs/rspec-core/example_groups/basic_structure

https://rspec.toolboxforweb.xyz/ja/docs/rspec-rails