【问题标题】:'rake spec' doesn't run with custom RAILS_ENV but 'rspec' and 'bundle exec rspec' do'rake spec' 不能与自定义 RAILS_ENV 一起运行,但 'rspec' 和 'bundle exec rspec' 可以
【发布时间】:2015-11-19 23:28:18
【问题描述】:

所以我遇到了一个奇怪的问题。我为运行 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 spec 都不会在 RAILS_ENV=ci 中运行,但 bundle exec rspec 工作正常。

有人可以解释这里发生了什么吗?我找不到任何合乎逻辑的方法。我是否偶然发现了 Rails 的 rake 任务中的错误?

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

  1. 此行为并非特定于我的机器,在每次测试前运行 bundle install 的干净 ruby​​:2.2 Docker 容器上的行为是相同的。由于它每次都加载一个干净的容器,因此“旧”版本的 gem 无法潜入。

  2. 为了进一步复制 Docker 容器的“干净状态”,我刚刚在我的机器上使用空 gemset 进行了测试,以排除 gem 版本冲突并得到相同的结果:http://pastebin.com/9u3MJaFw

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

  4. 如果rspec 和/或rspec-rails 没有被加载,rake 将失败并出现0 以外的退出代码,并输出如下内容:

    ~/not-myapp $ touch Rakefile

    ~/not-myapp $ rake 规范

    rake 中止!

    不知道如何构建任务'spec'

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

【问题讨论】:

  • 你能分享你的 Rakefile 吗?我无法在我的计算机上重现“rake”和“rake spec”之间的区别。
  • 我还在我的回复编辑中回复了您的第四条评论。
  • 我的 Rakefile 是 rails 标准文件,由以下两行组成:1) require File.expand_path('../config/application', __FILE__) 和 2) Rails.application.load_tasks

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


【解决方案1】:

几点:

rspec

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

耙子

gem rspec-rails 定义了一些 rake 任务,包括 spec 任务。但是,rake 只有在使用的环境中加载了 rspec gem 时才能运行此任务。如果您的 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 的某些冲突,或者由定义其他默认 rake 任务的其他一些 gem 引起的。

在任何情况下,这种行为都不是错误,并且可能特定于您的机器。我建议只使用 bundle exec rspec 来运行您的测试。


编辑:回应您的评论:

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

在您的情况下,文件spec 存在于您的项目中,并且是一个目录。所以当你执行rake spec时,如果任务spec不存在,它会加载你的spec文件,在没有任务运行之前什么都不做。

这就是为什么rake blublu 会失败,而rake specrake app 不会。

【讨论】:

  • 感谢您的回答!请查看更新后的问题以获取我的完整回复。
  • 这很好!刚刚用rake apprake lib 对其进行了测试,果然,同样的行为发生了! (退出 0,短暂暂停,无输出)。非常感谢您阐明这一点。
猜你喜欢
  • 2014-06-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-12
  • 1970-01-01
  • 1970-01-01
  • 2013-11-15
相关资源
最近更新 更多