RSpec の初期セットアップについてまとめました。
RSpecのセットアップ
以下のようにテスト用のプロジェクトを作成して確認していきたいと思います。
$ mkdir rspec_test && cd rspec_test $ bundle init $ vi Gemfile # railsのコメントアウト除去 $ bundle install --path vendor/bundle $ bundle exec rails new .
Gemfile に RSpecrspec-rails
と Factory Girlfactory_girl_rails
を追加してbundle install
を実行してください。Factory Girl はデフォルトの Fixture の代わりに使用します。
group :development, :test do gem 'rspec-rails', '~> 3.5' gem 'factory_girl_rails' end
インストールが終わると RSpec の基本的な設定をするために以下のコマンドを実行してください。
$ ./bin/rails generate rspec:install Running via Spring preloader in process 27988 Expected string default value for '--jbuilder'; got true (boolean) create .rspec create spec create spec/spec_helper.rb create spec/rails_helper.rb
.rspec
ファイルに以下のオプションを追加します。
--format documentation
Command line - RSpec Core - RSpec - Relish
RSpec はbundle exec rspec
や./bin/rake spec
でも実行できますが、
rspec コマンド用の binstub を作成してbin/rspec
で実行できるようにします。
$ bundle binstubs rspec-core
テストは無いですが RSpec が実行できれば完了です。
$ ./bin/rspec No examples found. Finished in 0.00049 seconds (files took 0.09147 seconds to load) 0 examples, 0 failures
既存の test ディレクトリは不要なので削除してください。
$ rm -rf test/
GitHub - rspec/rspec-rails: RSpec for Rails
GitHub - thoughtbot/factory_girl_rails: Factory Girl ♥ Rails
ジェネレータの設定変更
rails generate scaffold
等を使ってコードを追加すると、デフォルトの設定の場合は全ての RSpec ファイルが作成されます。
$ ./bin/rails g scaffold book name:string ... invoke rspec create spec/models/book_spec.rb invoke factory_girl create spec/factories/books.rb ... invoke rspec create spec/controllers/books_controller_spec.rb create spec/views/books/edit.html.erb_spec.rb create spec/views/books/index.html.erb_spec.rb create spec/views/books/new.html.erb_spec.rb create spec/views/books/show.html.erb_spec.rb create spec/routing/books_routing_spec.rb invoke rspec create spec/requests/books_spec.rb invoke helper create app/helpers/books_helper.rb invoke rspec create spec/helpers/books_helper_spec.rb
そこでconfig/application.rb
を編集してclass Application
の内部に以下のコードを追加します。ジェネレータを使用してコードを追加する時に自動生成されるスペックを指定することが可能です。この設定では fixtures (factory_girl) と controller のスペック以外は作成されないようにしています。
module Rspec2 class Application < Rails::Application config.generators do |g| g.test_framework :rspec, fixtures: true, view_specs: false, helper_specs: false, routing_specs: false, controller_specs: true, request_specs: false g.fixture_replacement :factory_girl, dir: "spec/factories" end end end
設定を追加して再度実行すると作成されるスペックが制限されているのがわかります。
$ ./bin/rails g scaffold book name:string invoke rspec create spec/models/book_spec.rb invoke factory_girl create spec/factories/books.rb ... invoke rspec create spec/controllers/books_controller_spec.rb invoke rspec invoke helper create app/helpers/books_helper.rb invoke rspec
development環境で使用する理由
Gemfile に RSpec と Factory Girl を追加するにあたって group に development 環境が含まれている理由としては Rails のジェネレータが使用するため必要だからです。
test 環境のみで使用するようにしてジェネレータを実際に試してみると、以下のように Test::Unit と Fixture のファイルが作成されます。
$ ./bin/rails g model user name:string Running via Spring preloader in process 28049 Expected string default value for '--jbuilder'; got true (boolean) invoke active_record create db/migrate/20161127140020_create_users.rb create app/models/user.rb invoke test_unit create test/models/user_test.rb create test/fixtures/users.yml
development 環境でも使用できるようにした場合、デフォルトのtest
ディレクトリからspec
ディレクトリに RSpec のファイル生成され、test/fixtures
の代わりに factory_girl のspec/factories
が生成されるようになります。
$ ./bin/rails g model user name:string Running via Spring preloader in process 31740 Expected string default value for '--jbuilder'; got true (boolean) invoke active_record create db/migrate/20161127150423_create_users.rb create app/models/user.rb invoke rspec create spec/models/user_spec.rb invoke factory_girl create spec/factories/users.rb
テスト用DBについて
新規で作成したプロジェクトであるならばテストDBを作成していないかもしれません。上記のようにモデルを作成した後に RSpec を実行すると失敗すると思います。
$ ./bin/rspec /Users/example/rspec_test/db/schema.rb doesn't exist yet. Run `rails db:migrate` to create it, then try again. If you do not intend to use a database, you should instead alter /Users/example/rspec_test/config/application.rb to limit the frameworks that will be loaded. /Users/example/rspec_test/vendor/bundle/ruby/2.3.0/gems/activerecord-5.0.0.1/lib/active_record/migration.rb:572:in `check_pending!': (ActiveRecord::PendingMigrationError) Migrations are pending. To resolve this issue, run: bin/rails db:migrate RAILS_ENV=test ...
migrate はRAILS_ENV=test
を指定しなくても、テスト実行時に未実行のマイグレーションファイルがある場合、自動でdb/schema.rb
からテスト用のDB設定をロードするようになっているため、基本的には不要です。
$ ./bin/rails db:migrate == 20161128104821 CreateUsers: migrating ====================================== -- create_table(:users) -> 0.0014s == 20161128104821 CreateUsers: migrated (0.0014s) =============================
もう一度 RSpec を実行すると成功しました。
$ ./bin/rspec User add some examples to (or delete) /Users/tasukujp/Documents/dev/rails/rspec3/spec/models/user_spec.rb (PENDING: Not yet implemented) Pending: (Failures listed here are expected and do not affect your suite's status) 1) User add some examples to (or delete) /Users/tasukujp/Documents/dev/rails/rspec3/spec/models/user_spec.rb # Not yet implemented # ./spec/models/user_spec.rb:4 Finished in 0.00124 seconds (files took 4.86 seconds to load) 1 example, 0 failures, 1 pending
テスト用DBを作成するだけであれば以下のコマンドどちらかでも大丈夫です。
$ ./bin/rake db:create RAILS_ENV=test $ ./bin/rake db:create:all