Windowsで Docker を用いて Rails 6.0 + MySQL の環境構築の続きです。
Windowsで Docker を用いて Rails 6.0 + MySQL の環境構築
https://codelabo.com/posts/20201010192152
前回はテストを入れずにRails環境を構築したので、今回はテストフレームワークとしてRspecを入れます。
Bundler::GemNotFoundエラーの対処方法も書いてます。
基本的に公式リポジトリ https://github.com/rspec/rspec-rails に書かれてる通りに進めればできると思います。
Gemfileに以下を追加
group :development, :test do
gem 'rspec-rails', '~> 4.0.1'
end
bundle install します。
docker-compose run app bundle install
設定ファイルを生成します。
docker-compose run app rails generate rspec:install
エラーがでました。
Traceback (most recent call last):
25: from /usr/local/bundle/gems/spring-2.1.1/bin/spring:49:in `<main>'
24: from /usr/local/bundle/gems/spring-2.1.1/lib/spring/client.rb:30:in `run'
23: from /usr/local/bundle/gems/spring-2.1.1/lib/spring/client/command.rb:7:in `call'
22: from /usr/local/bundle/gems/spring-2.1.1/lib/spring/client/server.rb:9:in `call'
21: from /usr/local/lib/ruby/2.7.0/rubygems/core_ext/kernel_require.rb:72:in `require'
20: from /usr/local/lib/ruby/2.7.0/rubygems/core_ext/kernel_require.rb:72:in `require'
19: from /usr/local/bundle/gems/spring-2.1.1/lib/spring/server.rb:9:in `<top (required)>'
18: from /usr/local/lib/ruby/2.7.0/rubygems/core_ext/kernel_require.rb:72:in `require'
17: from /usr/local/lib/ruby/2.7.0/rubygems/core_ext/kernel_require.rb:72:in `require'
16: from /usr/local/bundle/gems/spring-2.1.1/lib/spring/commands.rb:4:in `<top (required)>'
15: from /usr/local/bundle/gems/spring-2.1.1/lib/spring/commands.rb:33:in `<module:Spring>'
14: from /usr/local/lib/ruby/2.7.0/rubygems/core_ext/kernel_require.rb:92:in `require'
13: from /usr/local/lib/ruby/2.7.0/rubygems/core_ext/kernel_require.rb:92:in `require'
12: from /usr/local/lib/ruby/2.7.0/bundler/setup.rb:20:in `<top (required)>'
11: from /usr/local/lib/ruby/2.7.0/bundler/ui/shell.rb:88:in `silence'
10: from /usr/local/lib/ruby/2.7.0/bundler/ui/shell.rb:136:in `with_level'
9: from /usr/local/lib/ruby/2.7.0/bundler/setup.rb:20:in `block in <top (required)>'
8: from /usr/local/lib/ruby/2.7.0/bundler.rb:149:in `setup'
7: from /usr/local/lib/ruby/2.7.0/bundler/runtime.rb:20:in `setup'
6: from /usr/local/lib/ruby/2.7.0/bundler/runtime.rb:101:in `block in definition_method'
5: from /usr/local/lib/ruby/2.7.0/bundler/definition.rb:226:in `requested_specs'
4: from /usr/local/lib/ruby/2.7.0/bundler/definition.rb:237:in `specs_for'
3: from /usr/local/lib/ruby/2.7.0/bundler/definition.rb:170:in `specs'
2: from /usr/local/lib/ruby/2.7.0/bundler/spec_set.rb:80:in `materialize'
1: from /usr/local/lib/ruby/2.7.0/bundler/spec_set.rb:80:in `map!'
/usr/local/lib/ruby/2.7.0/bundler/spec_set.rb:86:in `block in materialize': Could not find diff-lcs-1.4.4 in any of the sources (Bundler::GemNotFound)
Bundler::GemNotFound
?
何を言ってるかわかりませんが、docker-compose build してみます。
Docker関連でエラーが出ると心が折れそうになるので、やめてほしいですね。
docker-compose build
もう一度Rails generate します。
docker-compose run app rails generate rspec:install
以下のログが出てうまくいきました。
Starting vdoll-rails_db_1 ... done Running via Spring preloader in process 66
create .rspec
create spec
create spec/spec_helper.rb
create spec/rails_helper.rb
テスト実行
以下のコマンドでテストを実行できます。
docker-compose run app rspec
# もしくは
docker-compose run app bundle exec rspec
他のターミナルなどで docker-compose up してるならrunではなくexecを使う方が高速です。
docker-compose exec app rspec
# もしくは
docker-compose exec app bundle exec rspec
上のコマンドだとすべてのテストが実行されるので、テストの数が多くなればかなり時間がかかるようになってしまいます。
なので、以下の様にファイル単位で実行することが多いかと思います。
docker-compose run app bundle exec rspec spec/*/*_spec.rb
余計なファイルが生成されないようにする
docker-compose exec app rails g controller Pages index show
みたいなコマンドで以下の様に必要ないテストファイルが生成されたりします。
それを生成されないようにするためには、\config\application.rb
に
module App
class Application < Rails::Application
# Rspec
config.generators.test_framework :rspec,
view_specs: false,
helper_specs: false,
controller_specs: false,
routing_specs: false
end
end
の様に追記します。
個人的にViewのテストを書かないのはFeatureSpecやSystemSpecのような統合テストが代わりになるから、コントローラーのテストを書かないのはRequestSpecや統合テストでカバーできるからなのかなと思いました。
RSpecのFeature Specを設定
rspec-railsに加えて、capybaraとselenium-webdriverをGemfileに追加。
Gemfile
group :development, :test do
gem 'rspec-rails', '~> 4.0.1'
end
group :test do
gem 'capybara' # 追加
end
bundle install
$ docker-compose run app bundle install
\spec\spec_helper.rb に
require 'capybara/rspec'
factory_botでテストデータを使いまわす
factory_botを使うことで user = create(:user) みたいにテストデータを使いまわせて便利です。
インストール
Gemfileにfactorybot, databasecleanerを追加。
database_cleanerはSystemSpecを利用する場合は不要です。
Gemfile
group :test do
gem 'factory_bot_rails'
gem 'database_cleaner'
end
DatabaseCleanerの設定
spec/rails_helper.rb
RSpec.configure do |config|
# FactoryBotの利用をON
config.include FactoryBot::Syntax::Methods
# DatabaseCleanerの設定
config.before(:suite) do
DatabaseCleaner.strategy = :truncation
end
config.before(:each) do
DatabaseCleaner.start
end
config.after(:each) do
DatabaseCleaner.clean
end
config.before(:all) do
DatabaseCleaner.start
end
config.after(:all) do
DatabaseCleaner.clean
end
end
テストデータの作成
これで問題なくテストデータを作れます。
spec/factories/users.rbファイルを作成して以下の様に書きます。
spec/factories/users.rb
FactoryBot.define do
factory :ilya, class: User do
name { 'Illyasviel von Einzbern' }
email { 'iliya@fate.pi' }
password { 'password' }
password_confirmation { 'password' }
end
factory :miyu, class: User do
name { '美遊・エーデルフェルト' }
email { 'miyu@fate.pi' }
password { 'password' }
password_confirmation { 'password' }
end
end
specファイルで以下の様に使います。
@user = create(:ilya)