メインコンテンツまでスキップ

ディレクトリ構造

仕様は通常、目的を説明するための標準的なディレクトリ構造に配置されます。

アプリケーション開発者は異なるディレクトリ構造を自由に使用することができます。ただし、正しい rspec-rails のサポート関数を含めるために、仕様には適切な対応するメタデータ :type の値が必要です。

  • モデルの仕様: type: :model
  • コントローラの仕様: type: :controller
  • リクエストの仕様: type: :request
  • フィーチャの仕様: type: :feature
  • ビューの仕様: type: :view
  • ヘルパーの仕様: type: :helper
  • メーラーの仕様: type: :mailer
  • ルーティングの仕様: type: :routing
  • ジョブの仕様: type: :job
  • システムの仕様: type: :system

例えば、ThingsController の仕様が spec/legacy/things_controller_spec.rb にある場合、仕様の RSpec.describe ブロックに単純に type: :controller のメタデータを付け加えます。

(# spec/legacy/things_controller_spec.rb
RSpec.describe ThingsController, type: :controller do
describe "GET index" do
# Examples
end
end

注意: 標準の RSpec 仕様では、デフォルトで追加のメタデータは必要ありません。

詳細については、rspec-core のドキュメントの メタデータの使用方法 を参照してください。

メタデータの自動追加

RSpecのバージョン3.0.0より前では、ファイルシステム上の場所に基づいてスペックにメタデータが自動的に追加されました。これは新規ユーザーにとって混乱を招き、一部のベテランユーザーにとっては望ましくありませんでした。

この動作を明示的に有効にする必要があります。

(# spec/rails_helper.rb
RSpec.configure do |config|
config.infer_spec_type_from_file_location!
end

この前提となる動作がチュートリアルで非常に一般的であるため、rails generate rspec:installによって生成されるデフォルトの設定では、これが有効になっています。

上記の標準的なディレクトリ構造に従い、infer_spec_type_from_file_location!を設定している場合、RSpecは各タイプに対して正しいサポート関数を自動的に含めます。

上記の標準的な構造に合わないカスタムディレクトリにメタデータを設定したい場合は、次のようにします。

(# set `:type` for serializers directory
RSpec.configure do |config|
config.define_derived_metadata(:file_path => Regexp.new('/spec/serializers/')) do |metadata|
metadata[:type] = :serializer
end
end

スペックの場所に関するヒント

spec/ディレクトリの構造は、一般的にapp/lib/と同様になるように推奨されています。これにより、対応するコードとスペックファイルを簡単に見つけることができます。

例:

app ├── controllers │ ├── application_controller.rb │ └── books_controller.rb ├── helpers │ ├── application_helper.rb │ └── books_helper.rb ├── models │ ├── author.rb │ └── book.rb └── views ├── books └── layouts lib ├── country_map.rb ├── development_mail_interceptor.rb ├── enviroment_mail_interceptor.rb └── tasks └── irc.rake spec ├── controllers │ └── books_controller_spec.rb ├── country_map_spec.rb ├── features │ └── tracking_book_delivery_spec.rb ├── helpers │ └── books_helper_spec.rb ├── models │ ├── author_spec.rb │ └── book_spec.rb ├── rails_helper.rb ├── requests │ └── books_spec.rb ├── routing │ └── books_routing_spec.rb ├── spec_helper.rb ├── tasks │ └── irc_spec.rb └── views └── books

標準のRailsスペックでは、:typeメタデータを指定する必要があります

Given a file named "spec/functional/widgets_controller_spec.rb" with:

require "rails_helper"

RSpec.describe WidgetsController, type: :controller do
it "responds successfully" do
get :index
expect(response.status).to eq(200)
end
end

When I run rspec spec

Then the example should pass.

非Rails関連のスペックは、デフォルトでは:typeメタデータを必要としません

Given a file named "spec/ledger/entry_spec.rb" with:

require "spec_helper"

Entry = Struct.new(:description, :us_cents)

RSpec.describe Entry do
it "has a description" do
is_expected.to respond_to(:description)
end
end

When I run rspec spec

Then the example should pass.

ファイルの場所からスペックのタイプを推測し、適切なメタデータを追加します

Given a file named "spec/controllers/widgets_controller_spec.rb" with:

require "rails_helper"

RSpec.configure do |config|
config.infer_spec_type_from_file_location!
end

RSpec.describe WidgetsController do
it "responds successfully" do
get :index
expect(response.status).to eq(200)
end
end

When I run rspec spec

Then the example should pass.

カノニカルディレクトリ内のスペックは、推測されたタイプを上書きできます

Given a file named "spec/routing/duckduck_routing_spec.rb" with:

require "rails_helper"

Rails.application.routes.draw do
get "/example" => redirect("http://example.com")
end

RSpec.configure do |config|
config.infer_spec_type_from_file_location!
end

# Due to limitations in the Rails routing test framework, routes that
# perform redirects must actually be tested via request specs
RSpec.describe "/example", type: :request do
it "redirects to example.com" do
get "/example"
expect(response).to redirect_to("http://example.com")
end
end

When I run rspec spec

Then the example should pass.