' rake spec'不会使用自定义RAILS_ENV运行,但是' rspec'和'捆绑exec rspec'做

时间:2015-08-26 04:15:53

标签: ruby-on-rails ruby rspec rake bundler

所以我有一个奇怪的问题。我有一个运行linux的CI服务器的自定义rails环境设置。环境正确加载,测试在CI服务器上运行,但前提是我使用bundle exec rspec而不是bundle exec rake specbundle exec rake运行它们。

当测试不运行时,它们仍会返回退出代码0,并且CI服务器假定构建成功,即使理论上构建可能已损坏。

在运行OS X的计算机上发生了相同的行为。

这是一个包含所有不同测试用例的控制台会话,以更好地说明发生了什么。

未指定RAILS_ENV

~/myapp $ rake
/Users/io/.rvm/rubies/ruby-2.2.0/bin/ruby -I/Users/io/.rvm/gems/ruby-2.2.0/gems/rspec-core-3.3.2/lib:/Users/io/.rvm/gems/ruby-2.2.0/gems/rspec-support-3.3.0/lib /Users/io/.rvm/gems/ruby-2.2.0/gems/rspec-core-3.3.2/exe/rspec --pattern spec/\*\*\{,/\*/\*\*\}/\*_spec.rb
...............................................

Finished in 4.34 seconds (files took 3.1 seconds to load)
47 examples, 0 failures
# -----
~/myapp $ rake spec
/Users/io/.rvm/rubies/ruby-2.2.0/bin/ruby -I/Users/io/.rvm/gems/ruby-2.2.0/gems/rspec-core-3.3.2/lib:/Users/io/.rvm/gems/ruby-2.2.0/gems/rspec-support-3.3.0/lib /Users/io/.rvm/gems/ruby-2.2.0/gems/rspec-core-3.3.2/exe/rspec --pattern spec/\*\*\{,/\*/\*\*\}/\*_spec.rb
...............................................

Finished in 3.8 seconds (files took 3.36 seconds to load)
47 examples, 0 failures
# -----
~/myapp $ rspec
...............................................

Finished in 3.87 seconds (files took 2.98 seconds to load)
47 examples, 0 failures
# -----
~/myapp $ bundle exec rake
/Users/io/.rvm/rubies/ruby-2.2.0/bin/ruby -I/Users/io/.rvm/gems/ruby-2.2.0/gems/rspec-core-3.3.2/lib:/Users/io/.rvm/gems/ruby-2.2.0/gems/rspec-support-3.3.0/lib /Users/io/.rvm/gems/ruby-2.2.0/gems/rspec-core-3.3.2/exe/rspec --pattern spec/\*\*\{,/\*/\*\*\}/\*_spec.rb
...............................................

Finished in 3.9 seconds (files took 3.03 seconds to load)
47 examples, 0 failures
# -----
~/myapp $ bundle exec rake spec
/Users/io/.rvm/rubies/ruby-2.2.0/bin/ruby -I/Users/io/.rvm/gems/ruby-2.2.0/gems/rspec-core-3.3.2/lib:/Users/io/.rvm/gems/ruby-2.2.0/gems/rspec-support-3.3.0/lib /Users/io/.rvm/gems/ruby-2.2.0/gems/rspec-core-3.3.2/exe/rspec --pattern spec/\*\*\{,/\*/\*\*\}/\*_spec.rb
...............................................

Finished in 3.64 seconds (files took 2.97 seconds to load)
47 examples, 0 failures
# -----
~/myapp $ bundle exec rspec
...............................................

Finished in 3.75 seconds (files took 2.95 seconds to load)
47 examples, 0 failures

一切都按预期工作

使用标准RAILS_ENV

结果与测试,开发或生产相同
~/myapp $ RAILS_ENV=test rake
/Users/io/.rvm/rubies/ruby-2.2.0/bin/ruby -I/Users/io/.rvm/gems/ruby-2.2.0/gems/rspec-core-3.3.2/lib:/Users/io/.rvm/gems/ruby-2.2.0/gems/rspec-support-3.3.0/lib /Users/io/.rvm/gems/ruby-2.2.0/gems/rspec-core-3.3.2/exe/rspec --pattern spec/\*\*\{,/\*/\*\*\}/\*_spec.rb
...............................................

Finished in 3.86 seconds (files took 3.07 seconds to load)
47 examples, 0 failures
# -----
~/myapp $ RAILS_ENV=test rake spec
/Users/io/.rvm/rubies/ruby-2.2.0/bin/ruby -I/Users/io/.rvm/gems/ruby-2.2.0/gems/rspec-core-3.3.2/lib:/Users/io/.rvm/gems/ruby-2.2.0/gems/rspec-support-3.3.0/lib /Users/io/.rvm/gems/ruby-2.2.0/gems/rspec-core-3.3.2/exe/rspec --pattern spec/\*\*\{,/\*/\*\*\}/\*_spec.rb
...............................................

Finished in 3.9 seconds (files took 3.02 seconds to load)
47 examples, 0 failures
# -----
~/myapp $ RAILS_ENV=test rspec    
...............................................

Finished in 3.82 seconds (files took 2.98 seconds to load)
47 examples, 0 failures
# -----
~/myapp $ RAILS_ENV=test bundle exec rake
/Users/io/.rvm/rubies/ruby-2.2.0/bin/ruby -I/Users/io/.rvm/gems/ruby-2.2.0/gems/rspec-core-3.3.2/lib:/Users/io/.rvm/gems/ruby-2.2.0/gems/rspec-support-3.3.0/lib /Users/io/.rvm/gems/ruby-2.2.0/gems/rspec-core-3.3.2/exe/rspec --pattern spec/\*\*\{,/\*/\*\*\}/\*_spec.rb
...............................................

Finished in 3.76 seconds (files took 2.91 seconds to load)
47 examples, 0 failures
# ------
~/myapp $ RAILS_ENV=test bundle exec rake spec
/Users/io/.rvm/rubies/ruby-2.2.0/bin/ruby -I/Users/io/.rvm/gems/ruby-2.2.0/gems/rspec-core-3.3.2/lib:/Users/io/.rvm/gems/ruby-2.2.0/gems/rspec-support-3.3.0/lib /Users/io/.rvm/gems/ruby-2.2.0/gems/rspec-core-3.3.2/exe/rspec --pattern spec/\*\*\{,/\*/\*\*\}/\*_spec.rb
...............................................

Finished in 3.83 seconds (files took 2.99 seconds to load)
47 examples, 0 failures
# -----
~/myapp $ RAILS_ENV=test bundle exec rspec    
...............................................

Finished in 3.83 seconds (files took 3.11 seconds to load)
47 examples, 0 failures

一切都很好,花花公子。

使用自定义RAILS_ENV

~/myapp $ RAILS_ENV=ci rake
/Users/io/.rvm/rubies/ruby-2.2.0/bin/ruby -I/Users/io/.rvm/gems/ruby-2.2.0/gems/rspec-core-3.3.2/lib:/Users/io/.rvm/gems/ruby-2.2.0/gems/rspec-support-3.3.0/lib /Users/io/.rvm/gems/ruby-2.2.0/gems/rspec-core-3.3.2/exe/rspec --pattern spec/\*\*\{,/\*/\*\*\}/\*_spec.rb
...............................................

Finished in 3.73 seconds (files took 3.03 seconds to load)
47 examples, 0 failures
# -----
~/myapp $ RAILS_ENV=ci rake spec
# No output, just a brief pause and back to shell prompt
~/myapp $ RAILS_ENV=ci rspec    
...............................................

Finished in 7.82 seconds (files took 2.96 seconds to load)
47 examples, 0 failures
# -----
~/myapp $ RAILS_ENV=ci bundle exec rake
# No output, just a brief pause and back to shell prompt
~/myapp $ RAILS_ENV=ci bundle exec rake spec
# No output, just a brief pause and back to shell prompt
~/myapp $ RAILS_ENV=ci bundle exec rspec    
...............................................

Finished in 7.77 seconds (files took 2.8 seconds to load)
47 examples, 0 failures

由于CI服务器的设置性质,我必须在bundle exec内运行测试。但令我难以置信的是,我的机器上RAILS_ENV=ci rake完美无缺,而RAILS_ENV=ci rake spec却无法运行。

但是当我将它们包裹在bundle exec rakerake specRAILS_ENV=ci bundle exec rspec:ci正常运行时。

有人可以解释这里发生了什么吗?我找不到符合逻辑的方法。我偶然发现了Rails中的一个错误'耙任务?

编辑:回复haradwaith's answer: 你提出了一些非常好的观点,第一点是现场(它直接运行rspec可执行文件),但我不能说你的答案充分解释了发生了什么。

  1. 此行为并非特定于我的机器,在干净的ruby上行为相同:2.2 Docker容器在每次测试之前运行bundle install。因为它每次都装载一个干净的容器,所以没有任何方法可以使用旧的"宝石的版本可以进入。

  2. 进一步复制"干净的石板"对于Docker容器,我只是在我的机器上使用空的gemset进行测试以排除gem版本冲突并获得相同的结果:http://pastebin.com/9u3MJaFw

  3. 我的Gemfile确实没有提到rspec-rails组。如果RAILS_ENV=ci rake gem没有被加载,那么没有参数的bundle exec就不会将Rspec作为默认的Rake任务运行,但显然可以。我们还可以看到它具有不同的行为,具体取决于它是否与bundle exec一起运行。我不相信与rspec-rails一起运行会#34;卸载" bundler如果在没有rspec的情况下运行它会设法自动加载它。

  4. 如果未加载rspec-rails和/或rake,则0将失败并返回{{1}}以外的退出代码,并吐出出类似的东西:

    〜/ not-myapp $ touch Rakefile

    〜/ not-myapp $ rake spec

    rake aborted!

    不知道如何构建任务'规范'

    (通过使用--trace运行任务查看完整跟踪)

1 个答案:

答案 0 :(得分:9)

有几点:

rspec的

rspecbundle exec rspec始终运行您的测试,因为它直接使用rspec可执行文件。

gem rspec-rails定义了一些rake任务,包括spec任务。但是,如果在已使用的环境中加载了rspec gem,rake将只能运行此任务。如果你的Gemfile中有这样的东西:

group :test, :development do
  gem 'rspec-rails', '~> 3.0'
end

spec任务命令仅适用于测试和开发环境,而不适用于RAILS_ENV=ci

建议始终使用bundle exec来运行ruby可执行文件。来自Bundler website

  

在某些情况下,运行不带bundle exec的可执行文件可能会起作用   可执行文件恰好安装在您的系统中,而不是   拉入任何与你的捆绑冲突的宝石。

     

然而,这是不可靠的,并且是相当痛苦的根源。   即使它看起来有效,但它可能在将来或以后都无法使用   另一台机器。

如果没有bundle exec,可执行文件可能会出现意外或不一致的行为,方法是混合已安装在您计算机上的其他gem或gem版本。

在您的情况下,RAILS_ENV=ci rake有效且RAILS_ENV=ci rake spec的事实不会因与旧版rspec-spec的某些冲突或某些其他定义其他默认值的宝石发生冲突而导致耙任务。

在任何情况下,此行为也不是错误,可能特定于您的计算机。我建议专门使用bundle exec rspec来运行测试。

编辑:回应你的评论:

4 - 即使未加载rake specrspec-rails也不崩溃的事实是一个棘手的部分。当您尝试运行任务example时,rake首先在已加载的rake文件中搜索任务example。如果找不到,它将检查项目中是否存在文件example。如果是,它将尝试从该文件执行so任务。

在您的情况下,文件spec存在于您的项目中,并且是一个目录。因此,当您执行rake spec时,如果任务spec不存在,它将加载您的spec文件,并且在没有任务在其中运行之前不执行任何操作。

这就是rake blublu失败的原因,但rake specrake app不会。