Rails アプリケーションのテストを高速化する技法として parallel_tests を導入した複数プロセスによる並列実行を取り挙げます。
parallel_tests のインストール
parallel_tests のインストールには Gemfile に以下の一行を追加して、bundle install
を行います。
gem 'parallel_tests', group: :development
テストを並列で実行する場合の留意点として、複数のプロセスから同一リソースを操作して、他方のプロセスが実行するテストデータに対して期待しない変更を及ばさないようにしておく必要がありますので、そのための Oracle の準備ステップに進みます。
接続先の Oracle を並列テスト実行できるようにする
Rails アプリケーションを Oracle を使って開発している場合、Oracle XE を使っていると思います。Oracle で parallel_tests を導入する場合は同一のデータベースへの接続ユーザーが異なれば別スキーマとなることを利用して、まず Oracle 側に parallel_tests で実行するプロセス分のユーザーを用意します。
データベースにユーザーを追加した後は database.yml に以下のような設定を行います。
test:
<<: *development
username: foobarbaz<%= ENV['TEST_ENV_NUMBER'] %>
password: foobarbaz
test
で接続する username
の方に、<%= ENV['TEST_ENV_NUMBER'] %>
と記すのがポイントです。
rake db:migrate を並列実行する
ここまでの準備が出来たら並列実行するプロセスの数を指定して RAILS_ENV=test bundle exec rake 'parallel:prepare[4]'
を実行することでスキーマのマイグレーションを行えます。ここではプロセス数を4つ指定しています。
あるいは CI 環境として rake db:schema:load
あるいは rake db:migrate:reset
をプロセス分実行したいという場合は以下のようなコマンドを組み込みます。
bundle exec parallel_test --exec 'rake db:schema:load RAILS_ENV=test' -n 4
bundle exec parallel_test --exec 'rake db:migrate:reset RAILS_ENV=test' -n 4
実行時エラーで困ったときは、parallel_tests のこの周辺のコードを読むとヒントになるかもしれません。
並列テスト実行
RSpec と Cucumber を合わせて実行する場合は次のとおりです。
RAILS_ENV=test bundle exec parallel_test spec --type rspec -n 4 --suffix '_spec.rb|.feature'
52分のテストを13分まで減らした実績もあるため、とりわけ CI 環境でのスローテストが深刻な場合に導入を検討することをおススメします。