This page looks best with JavaScript enabled

【RSpec】spec/rails_helper.rbを和訳&補足してみた

 ·   ·  ☕ 6 分で読めます
✏️

はじめに

rails_helperの設定をこんな風にしていますという記事はあるのですが、そのオプションによって何をしているのか今一つわからなかったので、自分用に和訳&補足してみました。

RSpecのバージョンは3.9です。

導入

$ rails g rspec:install

コマンドを打つと、.rspec, spec/rails_helper.rb, spec/spec_helper.rbファイルが生成されます。
rails_helper.rbはデフォルトではこのようになっています。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# This file is copied to spec/ when you run 'rails generate rspec:install'
require 'spec_helper'
ENV['RAILS_ENV'] ||= 'test'

require File.expand_path('../config/environment', __dir__)

# Prevent database truncation if the environment is production
abort("The Rails environment is running in production mode!") if Rails.env.production?
require 'rspec/rails'
# Add additional requires below this line. Rails is not loaded until this point!

# Requires supporting ruby files with custom matchers and macros, etc, in
# spec/support/ and its subdirectories. Files matching `spec/**/*_spec.rb` are
# run as spec files by default. This means that files in spec/support that end
# in _spec.rb will both be required and run as specs, causing the specs to be
# run twice. It is recommended that you do not name files matching this glob to
# end with _spec.rb. You can configure this pattern with the --pattern
# option on the command line or in ~/.rspec, .rspec or `.rspec-local`.
#
# The following line is provided for convenience purposes. It has the downside
# of increasing the boot-up time by auto-requiring all files in the support
# directory. Alternatively, in the individual `*_spec.rb` files, manually
# require only the support files necessary.
#
# Dir[Rails.root.join('spec', 'support', '**', '*.rb')].each { |f| require f }

# Checks for pending migrations and applies them before tests are run.
# If you are not using ActiveRecord, you can remove these lines.
begin
  ActiveRecord::Migration.maintain_test_schema!
rescue ActiveRecord::PendingMigrationError => e
  puts e.to_s.strip
  exit 1
end
RSpec.configure do |config|
  # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
  config.fixture_path = "#{::Rails.root}/spec/fixtures"

  # If you're not using ActiveRecord, or you'd prefer not to run each of your
  # examples within a transaction, remove the following line or assign false
  # instead of true.
  config.use_transactional_fixtures = true

  # RSpec Rails can automatically mix in different behaviours to your tests
  # based on their file location, for example enabling you to call `get` and
  # `post` in specs under `spec/controllers`.
  #
  # You can disable this behaviour by removing the line below, and instead
  # explicitly tag your specs with their type, e.g.:
  #
  #     RSpec.describe UsersController, :type => :controller do
  #       # ...
  #     end
  #
  # The different available types are documented in the features, such as in
  # https://relishapp.com/rspec/rspec-rails/docs
  config.infer_spec_type_from_file_location!

  # Filter lines from Rails gems in backtraces.
  config.filter_rails_from_backtrace!
  # arbitrary gems may also be filtered via:
  # config.filter_gems_from_backtrace("gem name")
end

このコメントアウトされた部分が今回のポイントです。
thisが何を示しているのかだとか、ちょっとした用語を噛み砕けるといいなと思います。

自分なりに和訳&補足してみた

rails generate rspec:installを実行すると、このファイルはspec/ディレクトリにコピーされます。

1
2
3
require 'spec_helper'
ENV['RAILS_ENV'] ||= 'test'
require File.expand_path('../config/environment', __dir__)

本番環境のときにデータベースのTRUNCATE1を防ぎます。

1
abort("The Rails environment is running in production mode!") if Rails.env.production?
1
require 'rspec/rails'

追加でrequireする場合はこの下に追加してください。この時点までRailsは読み込まれていません!

spec/support/配下のファイルを読み込む設定

カスタムマッチャやマクロ2などを記述したrubyファイルを読み込みたい場合、spec/support/配下に置いてください。

spec/配下にある_spec.rbで終わるファイルはbundle exec rspecコマンドを実行すると自動的に走ります。つまり、これをspec/support/内に置くと、読み込み時とテスト時の二回実行されることになります。
そのため、spec/support/_spec.rbで終わるファイルを置くのはやめましょう。

この様式3はコマンドを打つときに--patternを使うか、~/.rspec, .rspec, .rspec-localで設定できます。

以下の行は手間を省くために用意されています。この行を有効にするとspec/support/以下の全てのファイルが自動的に読み込まれるため、起動に時間がかかるという難点もあります。
代わりの方法として、それぞれの_spec.rbファイルでrequireを使って必要なファイルだけを読み込む方法もあります。

1
Dir[Rails.root.join('spec', 'support', '**', '*.rb')].each { |f| require f }

マイグレーションの設定

保留にされている4マイグレーションを確認し、テストを走らせる前にマイグレーションを適用します。

ActiveRecordを使わない場合、以下の行(beginからendまで)を削除できます。

1
2
3
4
5
6
begin
  ActiveRecord::Migration.maintain_test_schema!
rescue ActiveRecord::PendingMigrationError => e
  puts e.to_s.strip
  exit 1
end

(補足)
自動的にマイグレーションを行い、schemaとマイグレーションファイルに相違がある場合、例外を発生させます。

ActiveRecordのfixtureを使用する設定

もしActiveRecordやActiveRecordのfixtureを使用しない場合はこの行は必要ありません。

1
  config.fixture_path = "#{::Rails.root}/spec/fixtures"

(補足)例えばFactoryBotを使用する場合が当てはまりますが、他の人の設定を見たところ、わざわざ削除している人は少ないようです。

exampleごとにトランザクションを行う設定

ActiveRecordを使わない、またはトランザクション内で複数のexampleを走らせたい場合は、この行を削除するかオプションをtrueからfalseにしてください。

1
  config.use_transactional_fixtures = true

(補足)
デフォルトのtrueの場合、exampleごとにトランザクションが行われる設定になっています。つまり、exampleが始まるときにはきれいなデータベースが用意され、終わると全てのデータを削除します。
Database Cleanerなどを使って手動で削除する場合や、特定のSpecでだけトランザクションのロールバックを無効にする場合はfalseにします。

example については以下の説明を参考にしてください。

itはテストをexampleという単位にまとめる役割をします。
it do ... endの中のエクスペクテーション(期待値と実際の値の比較)がすべてパスすれば、そのexampleはパスしたことになります。
使えるRSpec入門・その1「RSpecの基本的な構文や便利な機能を理解する」

ファイルの場所に応じた機能を使用する設定

RSpec Railsでは、ファイルの場所に応じた動作を使用することができます。
例えば、spec/controllers配下のファイルでは、getpostを使うことができる仕様となっています。

以下の行を削除するとこの仕様が無効になります。
代わりに、

1
2
3
  RSpec.describe UsersController, type: :controller do
    # ...
  end

type: :controllerのように、明示的にタイプを記述することができます。

利用可能なタイプは、以下のサイトに記述しています。
https://relishapp.com/rspec/rspec-rails/docs

1
  config.infer_spec_type_from_file_location!

バックトレースをフィルタリングする設定

Railsで読み込まれたgemによるバックトレースをフィルタリングします。

1
  config.filter_rails_from_backtrace!

特定のgemをフィルタリングする場合、次の設定をしてください。

1
  config.filter_gems_from_backtrace("gem name")

(補足)
テスト失敗時のノイズを減らすための設定です。
テスト実行時に--backtraceを付けると、フィルタリングされていないバックトレースが表示されます。

(和訳はここまで)

ちなみに

FactoryBotやモジュールを使う場合は、以下のように読み込んでください。

1
2
3
4
5
6
7
8
RSpec.configure do |config|
  ...
  # config.filter_gems_from_backtrace("gem name")
  # この下に記述している人が多い印象です

  config.include FactoryBot::Syntax::Methods
  config.include LoginHelpers
end

おわりに

自分で翻訳したり調べたりすると、なんとなくRSpecの仕様への理解が深まった気がします。
また、公式ドキュメントはGoogle翻訳でも読みやすかったです。

元記事:Qiita


  1. テーブルに格納されているデータを全削除すること ↩︎

  2. ヘルパーメソッド ↩︎

  3. テスト実行時にどのファイルを実行するか pattern - Configuration - RSpec Core ↩︎

  4. db:migrateされていない状態 ↩︎

Share on

aiandrox
Written by
aiandrox
今日も楽しく明日も楽しく

目次