测试通过`testrb`,但使用Rails`rake test`崩溃?

时间:2013-10-11 14:18:04

标签: rake ruby-on-rails-4 carrierwave minitest

我有一个简单的测试来检查carrierwave上传器是否正常工作。

我为此使用minitest,测试在单独运行时有效,但不在Rails的rake test...环境下运行。

(测试代码如下。)

有效的方法:

  • 如果我运行ruby test/uploaders/image_file_uploader_test.rb,则测试通过。
  • 如果我运行testrb test/uploaders/image_file_uploader_test.rb,则测试通过。
  • 如果我从IRB手动调用测试中的所有行( Rails控制台),代码会执行预期的操作
  • 如果我创建一个小的Rake TestTask来运行该文件(任务也在下面复制),则测试通过。

不起作用的事情:

  • 如果我调用rake test test/uploaders/image_file_uploader_test.rb,我会被放入调试器(下面的堆栈跟踪)
  • 如果我致电zeus rake test test/uploaders/image_file_uploader_test.rb我也会被调入

有什么奇怪的:

如果我将调试器中的调用堆栈调到导致失败的测试行 - uploader.store!(@file) - 并直接用(rdb:1) p uploader.store!(@file)调用它,它就可以了!我的意思是,该方法按预期返回,文件出现在正确的目录中。

思考吗

我可能会在这里做一些非常愚蠢的事情。它必须与加载Rails环境的Rake任务有关,对吧?我是双重的 - 包括什么东西?是否与Rails环境中的初始化程序有关? (N.B.,当我从调试器执行store!时,它将文件存储在测试中指定的位置,因此它成功覆盖了Rails初始化程序。)

回溯

来自bundle exec rake test test/uploaders/*_test.rb

# Running tests:

/Users/leo/.rvm/gems/ruby-2.0.0-p195@portfolio_site/gems/carrierwave-0.9.0/lib/carrierwave/uploader/store.rb:75: `' (NilClass)
    from /Users/leo/.rvm/gems/ruby-2.0.0-p195@portfolio_site/gems/minitest-4.7.5/lib/minitest/unit.rb:926:in `_run_suite'
    from /Users/leo/.rvm/gems/ruby-2.0.0-p195@portfolio_site/gems/minitest-4.7.5/lib/minitest/parallel_each.rb:71:in `block in _run_suites'
    from /Users/leo/.rvm/gems/ruby-2.0.0-p195@portfolio_site/gems/minitest-4.7.5/lib/minitest/parallel_each.rb:71:in `map'
    from /Users/leo/.rvm/gems/ruby-2.0.0-p195@portfolio_site/gems/minitest-4.7.5/lib/minitest/parallel_each.rb:71:in `_run_suites'
    from /Users/leo/.rvm/gems/ruby-2.0.0-p195@portfolio_site/gems/minitest-4.7.5/lib/minitest/unit.rb:877:in `_run_anything'
    from /Users/leo/.rvm/gems/ruby-2.0.0-p195@portfolio_site/gems/minitest-4.7.5/lib/minitest/unit.rb:1085:in `run_tests'
    from /Users/leo/.rvm/gems/ruby-2.0.0-p195@portfolio_site/gems/minitest-4.7.5/lib/minitest/unit.rb:1072:in `block in _run'
    from /Users/leo/.rvm/gems/ruby-2.0.0-p195@portfolio_site/gems/minitest-4.7.5/lib/minitest/unit.rb:1071:in `each'
    from /Users/leo/.rvm/gems/ruby-2.0.0-p195@portfolio_site/gems/minitest-4.7.5/lib/minitest/unit.rb:1071:in `_run'
    from /Users/leo/.rvm/gems/ruby-2.0.0-p195@portfolio_site/gems/minitest-4.7.5/lib/minitest/unit.rb:1059:in `run'
    from /Users/leo/.rvm/gems/ruby-2.0.0-p195@portfolio_site/gems/minitest-4.7.5/lib/minitest/unit.rb:795:in `block in autorun'
/Users/leo/.rvm/gems/ruby-2.0.0-p195@portfolio_site/gems/carrierwave-0.9.0/lib/carrierwave/uploader/store.rb:75:
(rdb:1) where
--> #1 /Users/leo/.rvm/gems/ruby-2.0.0-p195@portfolio_site/gems/carrierwave-0.9.0/lib/carrierwave/uploader/store.rb:75:in `rmdir'
    #2 /Users/leo/.rvm/gems/ruby-2.0.0-p195@portfolio_site/gems/carrierwave-0.9.0/lib/carrierwave/uploader/store.rb:61:in `with_callbacks'
    #3 /Users/leo/.rvm/gems/ruby-2.0.0-p195@portfolio_site/gems/carrierwave-0.9.0/lib/carrierwave/uploader/store.rb:58:in `store!'
    #4 /Users/leo/Projects/PortfolioSite/test/uploaders/image_file_uploader_test.rb:38:in `test_upload_of_file'
    #5 /Users/leo/.rvm/gems/ruby-2.0.0-p195@portfolio_site/gems/minitest-4.7.5/lib/minitest/unit.rb:1258:in `run'
    #6 /Users/leo/.rvm/gems/ruby-2.0.0-p195@portfolio_site/gems/minitest-4.7.5/lib/minitest/unit.rb:933:in `_run_suite'
    #7 /Users/leo/.rvm/gems/ruby-2.0.0-p195@portfolio_site/gems/minitest-4.7.5/lib/minitest/parallel_each.rb:71:in `_run_suites'
    #8 /Users/leo/.rvm/gems/ruby-2.0.0-p195@portfolio_site/gems/minitest-4.7.5/lib/minitest/unit.rb:877:in `_run_anything'
    #9 /Users/leo/.rvm/gems/ruby-2.0.0-p195@portfolio_site/gems/minitest-4.7.5/lib/minitest/unit.rb:1085:in `run_tests'
    #10 /Users/leo/.rvm/gems/ruby-2.0.0-p195@portfolio_site/gems/minitest-4.7.5/lib/minitest/unit.rb:1072:in `_run'
    #11 /Users/leo/.rvm/gems/ruby-2.0.0-p195@portfolio_site/gems/minitest-4.7.5/lib/minitest/unit.rb:1059:in `run'
(rdb:1) up 3
#4 /Users/leo/Projects/PortfolioSite/test/uploaders/image_file_uploader_test.rb:38:in `test_upload_of_file'
(rdb:1) list
[33, 42] in /Users/leo/Projects/PortfolioSite/test/uploaders/image_file_uploader_test.rb
   33    end
   34
   35    # The whole point of this is to upload a file.
   36    def test_upload_of_file
   37      uploader = ImageFileUploader.new
=> 38      uploader.store!(@file)
   39      # Ensure the uploaded file is correct.
   40      assert_equal Digest::SHA2.file(@file).hexdigest, Digest::SHA2.file("#{STORE_PATH}/#{FILENAME}").hexdigest
   41    end
   42
(rdb:1) p uploader.store!(@file)
[:store_versions!]
(rdb:1)

致电p uploader.store!(@file)后,该文件已保存

来自zeus test test/uploaders/image_file_uploader_test.rb (这与上述非常类似)

/Users/leo/.rvm/gems/ruby-2.0.0-p195@portfolio_site/gems/carrierwave-0.9.0/lib/carrierwave/uploader/store.rb:75: `' (NilClass)
    from /Users/leo/.rvm/gems/ruby-2.0.0-p195@portfolio_site/gems/zeus-0.13.3/lib/zeus.rb:62:in `loop'
    from /Users/leo/.rvm/gems/ruby-2.0.0-p195@portfolio_site/gems/zeus-0.13.3/lib/zeus.rb:62:in `go'
    from /Users/leo/.rvm/gems/ruby-2.0.0-p195@portfolio_site/gems/zeus-0.13.3/lib/zeus.rb:78:in `block (3 levels) in go'
    from /Users/leo/.rvm/gems/ruby-2.0.0-p195@portfolio_site/gems/zeus-0.13.3/lib/zeus.rb:78:in `fork'
    from /Users/leo/.rvm/gems/ruby-2.0.0-p195@portfolio_site/gems/zeus-0.13.3/lib/zeus.rb:78:in `block (2 levels) in go'
    from /Users/leo/.rvm/gems/ruby-2.0.0-p195@portfolio_site/gems/zeus-0.13.3/lib/zeus.rb:73:in `each'
    from /Users/leo/.rvm/gems/ruby-2.0.0-p195@portfolio_site/gems/zeus-0.13.3/lib/zeus.rb:73:in `block in go'
    from /Users/leo/.rvm/gems/ruby-2.0.0-p195@portfolio_site/gems/zeus-0.13.3/lib/zeus.rb:62:in `loop'
    from /Users/leo/.rvm/gems/ruby-2.0.0-p195@portfolio_site/gems/zeus-0.13.3/lib/zeus.rb:62:in `go'
    from /Users/leo/.rvm/gems/ruby-2.0.0-p195@portfolio_site/gems/zeus-0.13.3/lib/zeus.rb:78:in `block (3 levels) in go'
    from /Users/leo/.rvm/gems/ruby-2.0.0-p195@portfolio_site/gems/zeus-0.13.3/lib/zeus.rb:78:in `fork'
    from /Users/leo/.rvm/gems/ruby-2.0.0-p195@portfolio_site/gems/zeus-0.13.3/lib/zeus.rb:78:in `block (2 levels) in go'
    from /Users/leo/.rvm/gems/ruby-2.0.0-p195@portfolio_site/gems/zeus-0.13.3/lib/zeus.rb:73:in `each'
    from /Users/leo/.rvm/gems/ruby-2.0.0-p195@portfolio_site/gems/zeus-0.13.3/lib/zeus.rb:73:in `block in go'
    from /Users/leo/.rvm/gems/ruby-2.0.0-p195@portfolio_site/gems/zeus-0.13.3/lib/zeus.rb:62:in `loop'
    from /Users/leo/.rvm/gems/ruby-2.0.0-p195@portfolio_site/gems/zeus-0.13.3/lib/zeus.rb:62:in `go'
    from -e:1:in `<main>'
/Users/leo/.rvm/gems/ruby-2.0.0-p195@portfolio_site/gems/carrierwave-0.9.0/lib/carrierwave/uploader/store.rb:75:
(rdb:1) where
--> #1 /Users/leo/.rvm/gems/ruby-2.0.0-p195@portfolio_site/gems/carrierwave-0.9.0/lib/carrierwave/uploader/store.rb:75:in `rmdir'
    #2 /Users/leo/.rvm/gems/ruby-2.0.0-p195@portfolio_site/gems/carrierwave-0.9.0/lib/carrierwave/uploader/store.rb:61:in `with_callbacks'
    #3 /Users/leo/.rvm/gems/ruby-2.0.0-p195@portfolio_site/gems/carrierwave-0.9.0/lib/carrierwave/uploader/store.rb:58:in `store!'
    #4 /Users/leo/Projects/PortfolioSite/test/uploaders/image_file_uploader_test.rb:38:in `test_upload_of_file'
    #5 /Users/leo/.rvm/gems/ruby-2.0.0-p195@portfolio_site/gems/minitest-4.7.5/lib/minitest/unit.rb:1258:in `run'
    #6 /Users/leo/.rvm/gems/ruby-2.0.0-p195@portfolio_site/gems/minitest-4.7.5/lib/minitest/unit.rb:933:in `_run_suite'
    #7 /Users/leo/.rvm/gems/ruby-2.0.0-p195@portfolio_site/gems/minitest-4.7.5/lib/minitest/parallel_each.rb:71:in `_run_suites'
    #8 /Users/leo/.rvm/gems/ruby-2.0.0-p195@portfolio_site/gems/minitest-4.7.5/lib/minitest/unit.rb:877:in `_run_anything'
    #9 /Users/leo/.rvm/gems/ruby-2.0.0-p195@portfolio_site/gems/minitest-4.7.5/lib/minitest/unit.rb:1085:in `run_tests'
    #10 /Users/leo/.rvm/gems/ruby-2.0.0-p195@portfolio_site/gems/minitest-4.7.5/lib/minitest/unit.rb:1072:in `_run'
    #11 /Users/leo/.rvm/gems/ruby-2.0.0-p195@portfolio_site/gems/minitest-4.7.5/lib/minitest/unit.rb:1059:in `run'
    #12 /Users/leo/.rvm/gems/ruby-2.0.0-p195@portfolio_site/gems/zeus-0.13.3/lib/zeus/m.rb:203:in `execute'
    #13 /Users/leo/.rvm/gems/ruby-2.0.0-p195@portfolio_site/gems/zeus-0.13.3/lib/zeus/m.rb:121:in `run'
    #14 /Users/leo/.rvm/gems/ruby-2.0.0-p195@portfolio_site/gems/zeus-0.13.3/lib/zeus/m.rb:106:in `run'
    #15 /Users/leo/.rvm/gems/ruby-2.0.0-p195@portfolio_site/gems/zeus-0.13.3/lib/zeus/rails.rb:190:in `test'
    #16 /Users/leo/.rvm/gems/ruby-2.0.0-p195@portfolio_site/gems/zeus-0.13.3/lib/zeus.rb:116:in `command'
    #17 /Users/leo/.rvm/gems/ruby-2.0.0-p195@portfolio_site/gems/zeus-0.13.3/lib/zeus.rb:80:in `go'
(rdb:1) up 3
#4 /Users/leo/Projects/PortfolioSite/test/uploaders/image_file_uploader_test.rb:38:in `test_upload_of_file'
(rdb:1) list
[33, 42] in /Users/leo/Projects/PortfolioSite/test/uploaders/image_file_uploader_test.rb
   33    end
   34
   35    # The whole point of this is to upload a file.
   36    def test_upload_of_file
   37      uploader = ImageFileUploader.new
=> 38      uploader.store!(@file)
   39      # Ensure the uploaded file is correct.
   40      assert_equal Digest::SHA2.file(@file).hexdigest, Digest::SHA2.file("#{STORE_PATH}/#{FILENAME}").hexdigest
   41    end
   42
(rdb:1) p uploader.store!(@file)
[:store_versions!]
(rdb:1)

代码

正在测试的课程

class ImageFileUploader < CarrierWave::Uploader::Base
  include CarrierWave::RMagick

  version :thumbnail do
    process resize_to_fill: [100,100]
  end

  def extension_white_list
    %w(jpg jpeg gif png)
  end
end

测试本身

require 'minitest/autorun'
require 'minitest/pride'
require 'minitest/debugger' if ENV['DEBUG']
require 'rmagick'
require 'carrierwave'
require_relative '../../app/uploaders/image_file_uploader'

class ImageFileUploaderTest < MiniTest::Unit::TestCase

  # Before any tests run, set up parameters.
  FILENAME = 'test_photo_1.jpg'
  STORE_DIR = 'tmp/uploads/store'
  CACHE_DIR = 'tmp/uploads/cache'
  STORE_PATH = File.join __dir__, '..', '..', STORE_DIR
  CACHE_PATH = File.join __dir__, '..', '..', CACHE_DIR

  # Override the store and cache dirs so we’re not reliant on Rails.
  class ::ImageFileUploader
    storage :file
    store_dir STORE_PATH
    cache_dir CACHE_PATH
  end

  # Before each test runs, set up a file to test with.
  def setup
    @file = File.new "#{__dir__}/../test_files/#{FILENAME}"
  end

  # After each test runs, clear the results directory so it doesn't influence other tests.
  def teardown
    FileUtils.rm_rf STORE_PATH
    FileUtils.rm_rf CACHE_PATH
  end

  # The whole point of this is to upload a file.
  def test_upload_of_file
    uploader = ImageFileUploader.new
    uploader.store!(@file)
    # Ensure the uploaded file is correct.
    assert_equal Digest::SHA2.file(@file).hexdigest, Digest::SHA2.file("#{STORE_PATH}/#{FILENAME}").hexdigest
  end

end

简单的佣金任务

require 'rake/testtask'

Rake::TestTask.new('dev:test') do |t|
  t.test_files = FileList['test/uploaders/*_test.rb']
end

Rails初始化程序(N.B.我认为测试与此隔离...)

CarrierWave.configure do |config|
  config.storage = :file

  # Override the directory where uploaded files will be stored.
  config.store_dir = -> do
    if model.nil?
      "uploads/other/#{Time.now.strftime("%F")}/#{Time.now.strftime("%H-%M-%S")}"
    else
      # This is a sensible default for uploaders that are meant to be mounted:
      "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
    end
  end

  # Override the directory where temp files will be stored.
  config.cache_dir = -> do
    # This is a better default because it prevents temp files from becoming public and is more consistent with the Rails directory structure.
    Rails.root.join('tmp/uploads')
  end
end

谢谢!

1 个答案:

答案 0 :(得分:0)

我已经解决了这个问题,虽然不是通过一个完全科学的过程,因为我正在改变代码中的其他内容,包括整个Rails环境,就像我一样。

当前的工作版本大大简化了Carrierwave初始化程序,将路径定义移动到上传程序,然后在测试中修补这些方法。

令人讨厌的是,基于初始化程序的方法的最初原因是为原始图像拾取了自定义目录,但是对于已处理的版本则没有。这似乎现在工作得很好,但是这个当前的代码与旧的代码有什么不同,我不确定。

Rails初始化程序

CarrierWave.configure do |config|
  config.storage = :file
end

<强>上传

class ImageFileUploader < CarrierWave::Uploader::Base
  include CarrierWave::RMagick

  version :thumbnail do
    process resize_to_fill: [100,100]
  end

  def extension_white_list
    %w(jpg jpeg gif png)
  end

  def store_dir
    if model.nil?
      "uploads/other/#{Time.now.strftime("%F")}/#{Time.now.strftime("%H-%M-%S")}"
    else
      # This is a sensible default for uploaders that are meant to be mounted:
      "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
    end
  end

  def cache_dir
    # This is a better default because it prevents temp files from becoming public and is more consistent with the Rails directory structure.
    Rails.root.join('tmp/uploads')
  end

end

<强>测试

require_relative '../test_helper'
require 'rmagick'
require 'carrierwave'
require_relative '../../app/uploaders/image_file_uploader'

class ImageFileUploaderTest < MiniTest::Unit::TestCase

  # Before any tests run, set up parameters.
  FILENAME = 'test_photo_1.jpg'
  STORE_DIR = 'tmp/uploads/store'
  CACHE_DIR = 'tmp/uploads/cache'
  STORE_PATH = File.join __dir__, '..', '..', STORE_DIR
  CACHE_PATH = File.join __dir__, '..', '..', CACHE_DIR

  # Override the store and cache dirs so we’re not reliant on Rails.
  class ::ImageFileUploader
    storage :file
    def store_dir; STORE_PATH; end
    def cache_dir; CACHE_PATH; end
  end

  # Before each test runs, set up a file to test with.
  def setup
    @file = File.new "#{__dir__}/../test_files/#{FILENAME}"
  end

  # After each test runs, clear the results directory so it doesn't influence other tests.
  def teardown
    FileUtils.rm_rf STORE_PATH
    FileUtils.rm_rf CACHE_PATH
  end

  # The whole point of this is to upload a file.
  def test_upload_of_file
    uploader = ImageFileUploader.new
    uploader.store!(@file)
    # Ensure the uploaded file is correct.
    assert_equal Digest::SHA2.file(@file).hexdigest, Digest::SHA2.file("#{STORE_PATH}/#{FILENAME}").hexdigest
  end

  # After each test, there is nothing to clean up, as teardown clears the output dir.
  def after_tests
  end

end

(NB包含test_helper与修复无关 - 在我开始工作之后,我将一些require移动到帮助程序,以便与其他测试重叠一些。)