【RSpec】テストスキップ対象フォルダをymlで管理する方法

## はじめに

弊社では、ベースとなるレポジトリをフォークして新規プロダクトを構築する方式を取っています。
このとき、フォークした先では使用しない機能も一緒に複製されます。
実際のプロダクトでは不要なテストが存在すると、以下の問題が発生します。

- テスト実行時間が長い
- 不要なテストが(なぜか)REDになる

これらを解決して、開発速度の向上を図りました。

![Qiita, note挿絵.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2688241/1197e559-22eb-5c46-f5e9-3b7c9b7aeea7.png)

## 目指すもの

`spec/spec_settings.yml` にてスキップ対象のフォルダをリストすることで、そのフォルダ内のテストを全てスキップするようにします。

```yml:spec_settings.yml
skippable_folders:
  # 設定されたフォルダ内のテストは全てスキップされる
  - test_skip
```

## 実装

### rails_helper.rbに実装

```ruby:rails_helper.rb
RSpec.configure do |config|
  config.before(:each) do |example|
    skippable_folders = YAML::load_file('spec/spec_settings.yml')['skippable_folders']
    if skippable_folders.any? { |f| example.file_path.include?(f) }
      skip "skippable対象フォルダ内のテストです"
    end
  end
end
```

### spec_settings.ymlにスキップ対象フォルダを指定

```yml:spec_settings.yml
skippable_folders:
  - test_skip
  - (その他にフォルダがあれば追加)
```

## テスト

### 準備

今回はテスト用に、以下の構成でフォルダとファイルを作成しました。

- spec/models/test
    - test_skip
        - skippable_spec.rb
    - test_run
        - run_spec.rb

それぞれのテストファイルを雑に作成します。

```ruby:skippable_spec.rb
require 'rails_helper'

describe 'TestSkip under model' do
  it 'runs the test' do
    puts "THIS TEST IS UNDER SKIPFOLDER"
    expect { puts 'test_skip folder under model is being tested' }.to output(/test_skip folder under model is being tested/).to_stdout
  end
end

describe 'TestSkip under model_2' do
  it 'runs the test' do
    puts "THIS TEST IS UNDER SKIPFOLDER"
    expect { puts 'test_skip folder under model is being tested' }.to output(/test_skip folder under model is being tested/).to_stdout
  end
end

describe 'TestSkip under model_3' do
  it 'runs the test' do
    puts "THIS TEST IS UNDER SKIPFOLDER"
    expect { puts 'test_skip folder under model is being tested' }.to output(/test_skip folder under model is being tested/).to_stdout
  end
end
```

これらのテストは実行されないため、ターミナルに`THIS TEST IS UNDER SKIPFOLDER`が表示されないことが正常です。


```ruby:run_spec.rb
require 'rails_helper'

describe 'TestDo under model' do
    it 'runs the test' do
      puts "THIS TEST IS UNDER RUNFOLDER"
      expect { puts 'test_do folder under model is being tested' }.to output(/test_do folder under model is being tested/).to_stdout
    end
end

describe 'TestDo under model_2' do
  it 'runs the test' do
    puts "THIS TEST IS UNDER RUNFOLDER"
    expect { puts 'test_do folder under model is being tested' }.to output(/test_do folder under model is being tested/).to_stdout
  end
end

describe 'TestDo under model_3' do
  it 'runs the test' do
    puts "THIS TEST IS UNDER RUNFOLDER"
    expect { puts 'test_do folder under model is being tested' }.to output(/test_do folder under model is being tested/).to_stdout
  end
end
```

これらのテストは実行されるため、ターミナルに`THIS TEST IS UNDER RUNFOLDER`が表示されることが正常です。


### 実行結果

```
$ bundle exec rspec spec/models/test
```

を実行した結果が以下です。

```terminal
THIS TEST IS UNDER RUNFOLDER
.THIS TEST IS UNDER RUNFOLDER
.THIS TEST IS UNDER RUNFOLDER
.***

~~略~~

Pending: (Failures listed here are expected and do not affect your suite's status)

  1) TestSkip under model runs the test
     # skippable対象フォルダ内のテストです
     # ./spec/models/test/test_skip/skippable_spec.rb:4

  2) TestSkip under model_2 runs the test
     # skippable対象フォルダ内のテストです
     # ./spec/models/test/test_skip/skippable_spec.rb:11

  3) TestSkip under model_3 runs the test
     # skippable対象フォルダ内のテストです
     # ./spec/models/test/test_skip/skippable_spec.rb:18


Finished in 0.23432 seconds (files took 12.8 seconds to load)
6 examples, 0 failures, 3 pending
```

ターミナルに`THIS TEST IS UNDER RUNFOLDER`が表示され、test_skip配下のテストが全てスキップされていることが確認できます。

## まとめ

今回は、不要なテストフォルダをリストに加えることで、
これにより無駄なストップがかからなくなり、開発速度の向上が見込まれます。

今後はテストだけでなく、コンポーネント化された機能自体をリストで選択できるようにしたいと考えています。