読者です 読者をやめる 読者になる 読者になる

【Rails】RSpecの初期セットアップ

スポンサーリンク

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