'rake spec'不能使用自定义RAILS_ENV运行,但'rspec'和'bundle exec rspec'可以运行

Ily*_* O. 7 ruby rake rspec ruby-on-rails bundler

所以我有一个奇怪的问题.我有一个运行linux的CI服务器的自定义rails环境设置.环境正确加载,测试在CI服务器上运行,但只有当我用bundle exec rspec而不是bundle exec rake spec或运行它们时bundle 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
Run Code Online (Sandbox Code Playgroud)

一切都按预期工作

使用标准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
Run Code Online (Sandbox Code Playgroud)

一切都很好,花花公子.

使用自定义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
Run Code Online (Sandbox Code Playgroud)

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

但是当我把它们包装成bundle exec既不是rake也没有rake spec运行RAILS_ENV=ci但是bundle exec rspec工作正常.

有人能解释一下这里发生了什么吗?我无法找到一种方法来使其具有任何逻辑意义.我偶然发现了Rails的rake任务中的错误吗?

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

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

  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 spec

    耙子流产了!

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

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

har*_*ith 9

几点:

rspec的

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

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

group :test, :development do
  gem 'rspec-rails', '~> 3.0'
end
Run Code Online (Sandbox Code Playgroud)

spec任务命令将只在测试和开发环境,而不是与工作RAILS_ENV=ci.

建议始终使用bundle exec运行ruby可执行文件.来自Bundler网站:

在某些情况下,bundle exec如果可执行文件恰好安装在您的系统中并且没有引入任何与您的软件包冲突的gem,那么运行可执行文件可能无效.

然而,这是不可靠的,并且是相当痛苦的根源.即使看起来它有效,它可能在将来或在另一台机器上不起作用.

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

在你的情况下,RAILS_ENV=ci rake工作和RAILS_ENV=ci rake spec不工作的事实可能是由于与旧版本rspec-spec或某些其他宝石定义其他默认rake任务的某些冲突引起的.

在任何情况下,这种行为也不是一个错误,可能是您的机器特有的.我建议专门bundle exec rspec用于运行测试.


编辑:回应你的评论:

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

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

这就是为什么rake blublu会失败,但是rake specrake app不会.