RSpec Rails
rspec-rails
は、デフォルトのテストフレームワークであるMinitestの代わりに、
Ruby on RailsにRSpecテストフレームワークを導入します。
RSpecでは、テストは単にアプリケーションコードを検証するスクリプトではありません。 それらは仕様(または_specs_とも呼ばれる)でもあります。 アプリケーションの振る舞いを詳細に説明したもので、 平易な英語で表現されます。
RSpec Railsの新しいバージョニング戦略に従って、次のように使用します:
- **
rspec-rails
6.x**はRails 6.1または7.xに使用します。 - **
rspec-rails
5.x**はRails 5.2または6.xに使用します。 - **
rspec-rails
4.x**はRails 5.xまたは6.xに使用します。 - **
rspec-rails
3.x**はRails 5.0より前のバージョンに使用します。 - **
rspec-rails
1.x**はRails 2.xに使用します。
インストール
重要 このREADME / ブランチは、6.1.xの安定リリースシリーズに対応しています。
このシリーズからのバグ修正のみがここに追加されます。
最新の不安定な機能を利用する場合は、Githubのmain
ブランチを参照してください。
-
アプリケーションの
Gemfile
のdevelopment
グループとtest
グループの両方にrspec-rails
を追加します:# Run against this stable release
group :development, :test do
gem 'rspec-rails', '~> 6.1.0'
end
# Or, run against the main branch
# (requires main-branch versions of all related RSpec libraries)
group :development, :test do
%w[rspec-core rspec-expectations rspec-mocks rspec-rails rspec-support].each do |lib|
gem lib, git: "https://github.com/rspec/#{lib}.git", branch: 'main'
end
end(
development
グループに追加する必要は厳密にはありませんが、 追加しない場合、ジェネレータやrakeタスクはRAILS_ENV=test
で先行する必要があります。) -
プロジェクトディレクトリ内で次の手順を実行します。
# Download and install
$ bundle install
# Generate boilerplate configuration files
# (check the comments in each generated file for more information)
$ rails generate rspec:install
create .rspec
create spec
create spec/spec_helper.rb
create spec/rails_helper.rb
アップグレード
既にプロジェクトで古いバージョンの rspec-rails
を使用している場合は、次のコマンドで最新バージョンにアップグレードします。
$ bundle update rspec-rails
RSpecはセマンティックバージョニングに従っています。つまり、「メジャーバージョン」のアップグレード(例:2.x → 3.x)には互換性のない変更が含まれます。バージョン2.x以下からアップグレードする場合は、rspec-rails
のアップグレードノートを確認して注意点を把握してください。
一般的なRSpecのアップグレードノートも確認してください。
使用方法
rails generate
を使用してボイラープレートのスペックを作成する
# RSpec hooks into built-in generators
$ rails generate model user
invoke active_record
create db/migrate/20181017040312_create_users.rb
create app/models/user.rb
invoke rspec
create spec/models/user_spec.rb
# RSpec also provides its own spec file generators
$ rails generate rspec:model user
create spec/models/user_spec.rb
# List all RSpec generators
$ rails generate --help | grep rspec
スペックの実行
# Default: Run all spec files (i.e., those matching spec/**/*_spec.rb)
$ bundle exec rspec
# Run all spec files in a single directory (recursively)
$ bundle exec rspec spec/models
# Run a single spec file
$ bundle exec rspec spec/controllers/accounts_controller_spec.rb
# Run a single example from a spec file (by line number)
$ bundle exec rspec spec/controllers/accounts_controller_spec.rb:8
# See all options for running specs
$ bundle exec rspec --help
オプション: bundle exec rspec
の出力が多すぎる場合は、bin/rspec
にバイナリスタブを生成して代わりに使用することもできます。
$ bundle binstubs rspec-core
RSpec DSLの基本(スペックの書き方)
RSpecでは、アプリケーションの振る舞いをほぼプレーンな英語で記述し、その後にテストコードで再度記述します。例えば、次のようになります。
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
rspec
を実行すると、このテストコードが実行され、プレーンな英語の記述を使用してアプリケーションがスペックに準拠しているかどうかのレポートが生成されます。
$ rspec --format documentation spec/models/post_spec.rb
Post
before publication
cannot have comments
Failures:
1) Post before publication cannot have comments
Failure/Error: expect { Post.create.comments.create! }.to raise_error(ActiveRecord::RecordInvalid)
expected ActiveRecord::RecordInvalid but nothing was raised
# ./spec/models/post.rb:4:in `block (3 levels) in <top (required)>'
Finished in 0.00527 seconds (files took 0.29657 seconds to load)
1 example, 1 failure
Failed examples:
rspec ./spec/models/post_spec.rb:3 # Post before publication cannot have comments
詳細なRSpec DSLの説明や多くの例については、公式のCucumberドキュメントであるRSpec Coreを参照してください。
便利なRails Matcher
RSpecでは、アサーションは_expectations_と呼ばれ、すべてのexpectationは_matcher_を中心に構築されます。expect(a).to eq(b)
のようにeq
マッチャーを使用しています。
[RSpecで標準で提供されているマッチャー][]に加えて、Railsシステムのさまざまな部分をテストするのに便利ないくつかの追加のマッチャーがあります。
RSpecマッチャー | デリゲート先 | 利用可能な場所 | ノート |
---|---|---|---|
be_a_new | すべて | 主にコントローラースペックで使用される | |
render_template | assert_template | リクエスト / コントローラー / ビュー | expect(response).to と組み合わせて使用します |
redirect_to | assert_redirect | リクエスト / コントローラー | expect(response).to と組み合わせて使用します |
route_to | assert_recognizes | ルーティング / コントローラー | expect(...).to route_to と組み合わせて使用します |
be_routable | ルーティング / コントローラー | expect(...).not_to be_routable と組み合わせて使用します | |
have_http_status | リクエスト / コントローラー / フィーチャー | ||
match_array | すべて | ActiveRecordオブジェクトの配列を比較するためのもの | |
have_been_enqueued | すべて | 設定が必要です: ActiveJob::Base.queue_adapter = :test | |
have_enqueued_job | すべて | 設定が必要です: ActiveJob::Base.queue_adapter = :test |
上記のリンクを参照して、各マッチャの使用例を確認してください。
RSpec Rails は他に何を追加しますか?
RSpec Rails の機能について詳しくは、公式のCucumberドキュメントを参照してください。
どのようなテストを書くべきですか?
RSpec Rails では、典型的なRailsアプリケーションのさまざまな部分をテストするために、10種類の異 なるスペックタイプが定義されています。
それぞれはRailsの組み込みのTestCase
クラスのいずれかを継承しており、Railsのデフォルトのテストで提供されるヘルパーメソッドはRSpecでも利用できます。
スペックタイプ | 対応するRailsテストクラス |
---|---|
model | |
controller | ActionController::TestCase |
mailer | ActionMailer::TestCase |
job | |
view | ActionView::TestCase |
routing | |
helper | ActionView::TestCase |
request | ActionDispatch::IntegrationTest |
feature | |
system | ActionDispatch::SystemTestCase |
上記のリンクを参照して、各仕様タイプの例を確認するか、指定された TestCase
クラスの公式Rails APIドキュメントを参照してください。
注意: これはチェックリストではありません。
アプリケーションのテスト方法について100人の開発者に尋ねると、100通りの異なる回答が得られます。
RSpec Railsは、良いテストの実践を促進するために慎重に選ばれた機能を提供していますが、それには「正しい」方法はありません。 最終的には、テストスイートの構成方法はあなた次第です。
仕様ファイルを作成する場合は、次のようにトップレベルの describe
ブロックにタイプを割り当てます。
# spec/models/user_spec.rb
RSpec.describe User, type: :model do
...
システム仕様、フィーチャ仕様、リクエスト仕様 - 違いは何ですか?
RSpec Railsは、いくつか のエンドツーエンド(アプリケーション全体)のテスト機能を提供し、クライアントとのやり取りを指定します。
システム仕様
または 受け入れテスト、ブラウザテスト、または エンドツーエンドテスト とも呼ばれるシステム仕様は、人間のクライアント の視点からアプリケーションをテストします。 テストコードは、ユーザーのブラウザの操作をたどります。
visit '/login'
fill_in 'Name', with: 'jdoe'
そして期待値はページの内容に関連しています。
expect(page).to have_text('Welcome')
システムスペックはRailsの組み込みのSystemTestCase
をラップしたものであり、Rails 5.1以降でのみ利用可能です。
(同じ目的を持つフィーチャースペックもありますが、この依存関係はありません。)
フィーチャースペック
Railsがシステムテストの機能を導入する前は、エンドツーエンドテストのための唯一のスペックタイプでした。 RSpecチームは現在公式にはシステムスペックを推奨していますが、フィーチャースペックはまだ完全にサポートされており、基本的に同じように見え、古いバージョンのRailsでも動作します。
一方、フィーチャースペックには重要な機能を動作させるために非自明な設定が必要です。 例えば、JavaScriptのテストや各テストが新しいDBの状態で実行されることを確認するためです。 システムスペックでは、この設定はすぐに提供されます。
システムスペックと同様に、フィーチャースペックにはCapybara gemが必要です。
Rails 5.1+では、システムテストの一部としてデフォルトで含まれていますが、アップグレードする余裕がない場合は、まずGemfile
の:test
グループに追加してください。
group :test do
gem "capybara"
end
リクエストスペック
リクエストスペックは、アプリケーションを_マシンクライアント_の視点からテストするためのものです。 HTTPリクエストで始まり、HTTPレスポンスで終わるため、フィーチャースペックよりも高速ですが、アプリのUIやJavaScriptを検証しません。
リクエストスペックは、コントローラースペックの高レベルな代替手段を提供します。 実際、RSpec 3.5以降、RailsチームとRSpecチームの両方がコントローラーの直接テストを非推奨し、リクエストスペックのような機能テストを推奨しています。
書く際には、次の質問に答えるようにしてください。 「与えられたHTTPリクエスト(動詞+パス+パラメータ)に対して、アプリケーションはどのようなHTTPレスポンスを返すべきですか?」
関連情報
RSpecの基本ライブラリ
- https://github.com/rspec/rspec
- https://github.com/rspec/rspec-core
- https://github.com/rspec/rspec-expectations
- https://github.com/rspec/rspec-mocks
推奨されるサードパーティの拡張機能
-
Capybara (Rails 5.1以降ではデフォルトで含まれています。 Capybara DSLをシステムスペックやフィーチャースペック以外の場所で使用するには、追加の設定が必要です。)