search
LoginSignup
27

More than 5 years have passed since last update.

posted at

Organization

springのbinstubオプションとparallel_testsを同時に使うと死ぬ

この記事は以下のバージョンにおいて再現する問題です

  • spring v1.1.1
  • parallel_tests v0.16.10

しばらく前に、Railsのコマンドを高速化するgemのspringの推奨インストール方法が変わった。
多分、Rails 4.1.0から標準になるからだと思うが。

で、今の公式のインストール方法によるとこんな感じ。

gem "spring", group: :development
gem "spring-commands-rspec", group: :development
gem "spring-commands-cucumber", group: :development
$ bundle install
$ bundle exec spring binstub --all

binstubを作ってWrapしておけば、透過的に早くなって楽だよねって感じです。
で、rspecとかcucumberにspringを対応させるgemを入れておけば、この二つもbinstubを作ってくれるのですが、これが問題です。

parallel_testsでrspecの実行コマンドを探すコードがこうなってます。

def determine_executable
  cmd = case
  when File.exists?("bin/rspec")
    "bin/rspec"
  when File.file?("script/spec")
    "script/spec"
  when ParallelTests.bundler_enabled?
    cmd = (run("bundle show rspec-core") =~ %r{Could not find gem.*} ? "spec" : "rspec")
    "bundle exec #{cmd}"
  else
    %w[spec rspec].detect{|cmd| system "#{cmd} --version > /dev/null 2>&1" }
  end

  cmd or raise("Can't find executables rspec or spec")
end

つまり、binstubで作られたコマンドが最初に引っ掛かります。
そうすると、勝手にspring経由でrspecが実行されて環境変数が切り替わらなくなります。
結果、データベースをプロセスごとに切り替えられなくなって、DB競合で死にます。

というわけで、binstubを使う場合は、rspecとかcucumberは外しておいた方が良さそうです。
parallel_testsを使わない場合は便利なんですけどね…。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
27