【Rails】RSpec便利なカスタマイズ

# カスタマイズ一覧
```spec_helper.rb
RSpec.configure do |config|
  # 1
  config.filter_run_when_matching :focus

  # 2
  config.example_status_persistence_file_path = "spec/examples.txt"

  # 3
  config.disable_monkey_patching!

  # 4
  if config.files_to_run.one?
    config.default_formatter = "doc"
  end

  # 5
  config.profile_examples = 10

  # 6
  config.order = :random

  # 7
  Kernel.srand config.seed
end
```

## 1. 特定のテストのみ実行する方法
### 方法1
```terminal
// rspec ファイルパス:行数
$ rspec spec/models/user_spec.rb:12
```

ファイル名と行数を指定すると，テストを限定して実行することができます．
しかし行数を確認する作業や，複数ファイルに跨ったテストは大変です……


### 方法２
そこで以下の設定をします．
```spec_helper.rb
RSpec.configure do |config|
  config.filter_run_when_matching :focus
end
```
テストブロックの先頭に`f`をつけることで実行するテストを指定することができます．

e.g.: `fdescribe`, `fcontext`, `fit`
```user_spec.rb
RSpec.describe User, type: :model do
  describe 'validations' do
    it 'is valid with valid attributes' do
        # ...
    end

    # このテストのみ実行される！
    fit 'is not valid without a user_name' do 
        # ...
    end

    it 'is not valid without an email' do
        # ...
    end
  end
end
```
:::note warn
commitする時`f`の消し忘れに注意してください！
:::

### 方法3
```terminal
$ rspec --example '実行したいexampleやdescribeの名前の一部'
```

e.g.:
```
# describeやexampleにtestが含まれているものが実行される
# (SQLで言うところの LIKE '%test%')
$ rspec --example 'test'
```
詳細は[こちら](https://qiita.com/s_yasunaga/items/cc7489ee4e51ca196c43#%E7%89%B9%E5%AE%9A%E3%81%AEexample%E3%82%84describe%E3%81%AE%E3%81%BF%E5%AE%9F%E8%A1%8C)を参照


## 2. 前回失敗したテストのみ実行する方法
```terminal
$ rspec --only-failures
```
これを実行するには以下の設定が必要です．
```spec_helper.rb
RSpec.configure do |config|
  config.example_status_persistence_file_path = "spec/examples.txt"
end
```
仕組みとしてはRSpec実行後，`spec/examples.txt`にテスト結果を一時保管しておくことで，失敗したテストだけを実行できるわけです．


ちなみに以下のコマンドは`--only-failures`を適用し，1回失敗したら中断するコマンドです．
```terminal
$ rspec --next-failure
```


## 3. モンキーパッチを無効にする
> ## モンキーパッチとは？
> モンキーパッチは、プログラミングにおいて既存のコードを変更する技術です。Rubyでは、既存のクラスやモジュールに新しいメソッドを追加したり、既存のメソッドを上書きしたりすることが可能です。これにより、アプリケーションの特定のニーズに合わせてカスタマイズできます。
[参考](https://qiita.com/YutoYasunaga/items/7dc5c418fc90f84f274e#:~:text=%E3%83%A2%E3%83%B3%E3%82%AD%E3%83%BC%E3%83%91%E3%83%83%E3%83%81%E3%81%AF%E3%80%81%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E3%81%AB%E3%81%8A%E3%81%84%E3%81%A6,%E5%90%88%E3%82%8F%E3%81%9B%E3%81%A6%E3%82%AB%E3%82%B9%E3%82%BF%E3%83%9E%E3%82%A4%E3%82%BA%E3%81%A7%E3%81%8D%E3%81%BE%E3%81%99%E3%80%82)

新しいメソッドを追加したり，既存メソッドのバグ修正に役立ちますが，他への影響や可読性が低下する等のデメリットもあるそうです．

```spec_helper.rb
RSpec.configure do |config|
  config.disable_monkey_patching!
end
```

### ##追記
monkey_patchを無効にするとテストコードの1行目に`RSpec.describe`と書く必要があります．
テストコードは`RSpec`を明示的に書くことを推奨してるそうです．
つまり，`disable_monkey_patching`を有効にして，テストコードは`RSpec.describe クラス名…`から始めるようにしましょう．



## 4. 単一ファイルのテスト時に詳細な出力をする

```spec_helper.rb
RSpec.configure do |config|
  config.default_formatter = "doc"
end
```
この設定をすると単一ファイルをテストする際，出力結果が詳細になります．
クラス名とメソッド名，各テストケースの説明が出力されます．
```terminal
ClassName
  method_name
    behaves in one way under condition x
    behaves in another way under condition y
```

## 5. 実行時間が遅いテストを表示
```spec_helper.rb
RSpec.configure do |config|
  config.profile_examples = 10
end
```
RSpec実行後，テスト結果と共に実行時間が遅いテストから上位10件表示されます．
ボトルネックになってる箇所の特定に使えそうです．
出力件数を変えることができますが，10件のままで良いと思います．

```terminal
Top 10 slowest examples (0.35 seconds, 79.9% of total time):
  ClassName method_name behaves in one way under condition x
    0.12 seconds ./spec/models/class_name_spec.rb:12
  AnotherClassName another_method_name behaves in another way under condition y
    0.10 seconds ./spec/models/another_class_name_spec.rb:20
...
```

## 6. テストの実行順序を指定
```spec_helper.rb
RSpec.configure do |config|
  config.order = :random
end
```
テストの実行順序をランダムにする設定です．この設定によって特定の順序に依存していないか検出することができます．また，ランダムな実行によって潜在的なエラーを発見することができます．


## 7. 
```spec_helper.rb
RSpec.configure do |config|
  Kernel.srand config.seed
end
```

乱数生成のシードを設定するための設定です．
これにより，常に同じ乱数のシーケンスを生成します．
ランダムな動作を一定に保ちつつ，テスト結果を再現することが可能です．

e.g.: シード値`12345`を用いて前回と同じ順序でテストを実行する場合
```terminal
$ rspec --seed 12345
```

## 参考文献
https://zenn.dev/harasho/articles/execute-only-specific-tests

https://qiita.com/s_yasunaga/items/cc7489ee4e51ca196c43

https://uvb-76.hatenablog.com/entry/2018/09/23/151549

### 追記(2024/05/08)
モンキーパッチの説明を追加しました．