gpt4 book ai didi

ruby-on-rails - capybara 上传图片问题

转载 作者:行者123 更新时间:2023-11-28 21:22:23 25 4
gpt4 key购买 nike

我需要使用 Capybara 和 Selenium 测试文件上传页面。

我写了这个测试:

require 'rails_helper'

describe 'Images', type: :feature do
before(:each) do
@user = create(:user)
visit '/users/sign_in'
fill_in 'sing-in-email-input', with: @user.email
fill_in 'sign-in-password-input', with: @user.password
click_button 'btn-sign-in'
visit '/categories'
click_on 'btn-new-category'
expect(current_path) == new_category_path
fill_in 'category_name', with: 'Test'
click_button 'btn-create category'
visit '/categories'
first('.fa', :visible => false).click
expect(current_path) == category_path(id: Category.last.slug.to_s)
end

it 'should allow a registered user to create image and go to it page', js: true do
click_on 'btn-upload-images'
expect(current_path) == new_image_path(id: Category.last.slug.to_s)
attach_file('image[image]',
File.join(Rails.root, '/spec/fixtures/solnce-kosmos-merkuriy.jpg'), :visible => false)
click_on('btn-upload-img')
end
end

我无法继续编写此测试并检查此图片是否已成功上传,因为在这一行:

click_on('btn-upload-img')

我遇到了这个错误:

Failure/Error: raise ActionController::RoutingError, "No route matches [#{env['REQUEST_METHOD']}] #{env['PATH_INFO'].inspect}"

ActionController::RoutingError:
No route matches [GET] "/home/Anton-S/RubymineProjects/rails_projects/gallery/spec/support/uploads/image/image/8790/solnce-kosmos-merkuriy.jpg"
# /var/lib/gems/2.3.0/gems/railties-5.1.4/lib/rails/rack/logger.rb:36:in `call_app'
# /var/lib/gems/2.3.0/gems/railties-5.1.4/lib/rails/rack/logger.rb:24:in `block in call'
# /var/lib/gems/2.3.0/gems/railties-5.1.4/lib/rails/rack/logger.rb:24:in `call'
# /var/lib/gems/2.3.0/gems/rack-2.0.3/lib/rack/method_override.rb:22:in `call'
# /var/lib/gems/2.3.0/gems/rack-2.0.3/lib/rack/runtime.rb:22:in `call'
# /var/lib/gems/2.3.0/gems/rack-2.0.3/lib/rack/sendfile.rb:111:in `call'
# /var/lib/gems/2.3.0/gems/railties-5.1.4/lib/rails/engine.rb:522:in `call'
# /var/lib/gems/2.3.0/gems/rack-2.0.3/lib/rack/urlmap.rb:68:in `block in call'
# /var/lib/gems/2.3.0/gems/rack-2.0.3/lib/rack/urlmap.rb:53:in `each'
# /var/lib/gems/2.3.0/gems/rack-2.0.3/lib/rack/urlmap.rb:53:in `call'
# /var/lib/gems/2.3.0/gems/capybara-2.16.1/lib/capybara/server.rb:44:in `call'
# /var/lib/gems/2.3.0/gems/rack-2.0.3/lib/rack/handler/webrick.rb:86:in `service'
# ------------------
# --- Caused by: ---
# Capybara::CapybaraError:
# Your application server raised an error - It has been raised in your test code because Capybara.raise_server_errors == true
# /var/lib/gems/2.3.0/gems/capybara-2.16.1/lib/capybara/session.rb:145:in `raise_server_error!'

Finished in 17.15 seconds (files took 2.55 seconds to load)
133 examples, 1 failure

Failed examples:

rspec ./spec/features/images_spec.rb:20 # Images should allow a registered user to create image and go to it page

我检查过我确实有这个文件

/spec/fixtures/solnce-kosmos-merkuriy.jpg

在正确的地方。

这是我的/config/initializers/carrierwave.rb

if Rails.env.test? || Rails.env.cucumber?
CarrierWave.configure do |config|
config.storage = :file
config.enable_processing = false
end

# make sure our uploader is auto-loaded
ImageUploader

# use different dirs when testing
CarrierWave::Uploader::Base.descendants.each do |klass|
next if klass.anonymous?
klass.class_eval do
def cache_dir
"#{Rails.root}/spec/support/uploads/tmp"
end

def store_dir
"#{Rails.root}/spec/support/uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
end
end
end

我的rails_helper.rb

require 'support/factory_bot'
require 'spec_helper'
require 'shoulda/matchers'
require 'capybara/rspec'
ENV['RAILS_ENV'] ||= 'test'
require File.expand_path('../../config/environment', __FILE__)
abort("The Rails environment is running in production mode!") if Rails.env.production?
require 'rspec/rails'

ActiveRecord::Migration.maintain_test_schema!


module DeviseRequestSpecHelpers

include Warden::Test::Helpers

def sign_in(resource_or_scope, resource = nil)
resource ||= resource_or_scope
scope = Devise::Mapping.find_scope!(resource_or_scope)
login_as(resource, scope: scope)
end

def sign_out(resource_or_scope)
scope = Devise::Mapping.find_scope!(resource_or_scope)
logout(scope)
end

end

RSpec.configure do |config|
Capybara.ignore_hidden_elements = false

config.fixture_path = "#{::Rails.root}/spec/fixtures"

config.use_transactional_fixtures = true

config.infer_spec_type_from_file_location!

config.filter_rails_from_backtrace!
config.include Devise::Test::ControllerHelpers, type: :controller
config.include DeviseRequestSpecHelpers, type: :request
end

Shoulda::Matchers.configure do |config|
config.integrate do |with|
with.test_framework :rspec

with.library :rails
end
end

我的spec_helper.rb

RSpec.configure do |config|
config.expect_with :rspec do |expectations|
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
end

config.mock_with :rspec do |mocks|
mocks.verify_partial_doubles = true
end

config.shared_context_metadata_behavior = :apply_to_host_groups
end

此图片上传页面的 View 模板:

.row.main-new-image
= form_for @image, url: create_image_path, html: {multipart: true, method: :post, remote: true } do |form|
#new_image_error_explanation
.field
.p.text-center
%span.btn.btn-new-image{id: 'new-image-button'}
%p#p-new-image-button Choose image
\#{form.file_field :image, id: 'new-image-id'}
.field
= form.hidden_field :user_id, value: current_user.id
.actions
.p.text-center
= form.submit 'Upload', class: 'btn button-upload-img', id: 'btn-upload-img'

我所有其他的 Capybara 和 RSpec 测试都工作正常。

请帮助我了解此问题的原因以及如何解决和预防。

如果可以帮助解决这个问题,我可以提供更多信息。

UPDATE 1

阅读 Thomas Walpole 的评论后,我决定更新我的代码并尝试一些其他功能。我包括新 gem

gem 'database_cleaner'

我还添加了新代码来清除测试上传的代码。这里更新了 rails_helper.rb

require 'support/factory_bot'
require 'spec_helper'
require 'shoulda/matchers'
require 'capybara/rspec'
ENV['RAILS_ENV'] ||= 'test'
require File.expand_path('../../config/environment', __FILE__)
Dir[Rails.root.join('spec/support/**/*.rb')].each { |f| require f }
abort("The Rails environment is running in production mode!") if Rails.env.production?
require 'rspec/rails'

ActiveRecord::Migration.maintain_test_schema!
module DeviseRequestSpecHelpers

include Warden::Test::Helpers

def sign_in(resource_or_scope, resource = nil)
resource ||= resource_or_scope
scope = Devise::Mapping.find_scope!(resource_or_scope)
login_as(resource, scope: scope)
end

def sign_out(resource_or_scope)
scope = Devise::Mapping.find_scope!(resource_or_scope)
logout(scope)
end
end

RSpec.configure do |config|
Capybara.javascript_driver = :selenium
Capybara.ignore_hidden_elements = true
Capybara.register_driver :selenium do |app|
Capybara::Selenium::Driver.new(app, browser: :firefox)
end

config.include Capybara::DSL
config.fixture_path = "#{::Rails.root}/spec/fixtures"
config.use_transactional_fixtures = true
config.before(:suite) do
DatabaseCleaner.strategy = :transaction
DatabaseCleaner.clean_with(:truncation)
end

config.around(:each) do |example|
DatabaseCleaner.cleaning do
example.run
end
end

config.after(:all) do
if Rails.env.test?
FileUtils.rm_rf(Dir["#{Rails.root}/spec/support/uploads"])
end
end
config.infer_spec_type_from_file_location!
config.filter_rails_from_backtrace!
config.include Devise::Test::ControllerHelpers, type: :controller
config.include DeviseRequestSpecHelpers, type: :request
end

Shoulda::Matchers.configure do |config|
config.integrate do |with|
with.test_framework :rspec

with.library :rails
end
end

这是我更新的测试

require 'rails_helper'

describe 'Images', type: :feature do
before(:each) do
@user = create(:user)
visit '/users/sign_in'
fill_in 'sing-in-email-input', with: @user.email
fill_in 'sign-in-password-input', with: @user.password
click_button 'btn-sign-in'
visit '/categories'
click_on 'btn-new-category'
have_current_path(new_category_path)
fill_in 'category_name', with: 'Test'
click_button 'btn-create category'
visit '/categories'
first('.fa', :visible => false).click
have_current_path(category_path(id: Category.last.slug.to_s))
end

#ISSUE WITH
it 'should allow a registered user to create image and go to it page', :driver => :selenium do
click_on 'btn-upload-images'
have_current_path(new_image_path(id: Category.last.slug.to_s))
attach_file('image[image]',
File.join(Rails.root, '/spec/fixtures/solnce-kosmos-merkuriy.jpg'), :visible => false)
click_on('btn-upload-img')
end
end

正如 Thomas Walpole 告诉我的那样,我检查了测试日志并看到了下一个(关于当前测试):

Started GET "/en/categories/test/new_image" for 127.0.0.1 at 2018-01-30 14:33:26 +0200
Processing by ImagesController#new as HTML
Parameters: {"locale"=>"en", "id"=>"test"}
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2 [["id", 22], ["LIMIT", 1]]
(0.2ms) SAVEPOINT active_record_2
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2 [["id", 22], ["LIMIT", 1]]
SQL (0.3ms) INSERT INTO "user_actions" ("user_id", "action_type", "url", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5) RETURNING "id" [["user_id", 22], ["action_type", "navigation"], ["url", "http://127.0.0.1:38226/en/categories/test/new_image"], ["created_at", "2018-01-30 12:33:26.645909"], ["updated_at", "2018-01-30 12:33:26.645909"]]
(0.1ms) RELEASE SAVEPOINT active_record_2
Rendering images/new.html.haml within layouts/application
Rendered images/_form.html.haml (5.2ms)
Rendered images/new.html.haml within layouts/application (7.5ms)
Category Load (1.1ms) SELECT DISTINCT categories.*, COUNT(images.*) AS images_count, categories.*, COUNT(likes.*) AS likes_count, categories.*, COUNT(comments.*) AS comments_count FROM "categories" LEFT OUTER JOIN "images" ON "images"."category_id" = "categories"."id" LEFT OUTER JOIN "images" "images_categories_join" ON "images_categories_join"."category_id" = "categories"."id" LEFT OUTER JOIN "likes" ON "likes"."image_id" = "images_categories_join"."id" LEFT OUTER JOIN "images" "images_categories_join_2" ON "images_categories_join_2"."category_id" = "categories"."id" LEFT OUTER JOIN "comments" ON "comments"."image_id" = "images_categories_join_2"."id" GROUP BY categories.id ORDER BY images_count DESC, likes_count DESC, comments_count DESC LIMIT $1 [["LIMIT", 5]]
Rendered layouts/_header.html.haml (4.3ms)
Rendered layouts/_footer.haml (0.0ms)
Completed 200 OK in 21ms (Views: 12.6ms | ActiveRecord: 2.1ms)
Category Load (0.6ms) SELECT "categories".* FROM "categories" ORDER BY "categories"."id" DESC LIMIT $1 [["LIMIT", 1]]
Started POST "/en/categories/test/create_image" for 127.0.0.1 at 2018-01-30 14:33:26 +0200
Processing by ImagesController#create as JS
Parameters: {"utf8"=>"✓", "image"=>{"image"=>#<ActionDispatch::Http::UploadedFile:0x0000000ae4e008 @tempfile=#<Tempfile:/tmp/RackMultipart20180130-28977-1nptliu.jpg>, @original_filename="solnce-kosmos-merkuriy.jpg", @content_type="image/jpeg", @headers="Content-Disposition: form-data; name=\"image[image]\"; filename=\"solnce-kosmos-merkuriy.jpg\"\r\nContent-Type: image/jpeg\r\n">, "user_id"=>"22"}, "commit"=>"Upload", "locale"=>"en", "id"=>"test"}
Category Load (0.2ms) SELECT "categories".* FROM "categories" WHERE "categories"."slug" = $1 LIMIT $2 [["slug", "test"], ["LIMIT", 1]]
User Load (0.1ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2 [["id", 22], ["LIMIT", 1]]
(0.3ms) SAVEPOINT active_record_2
User Load (0.3ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2 [["id", 22], ["LIMIT", 1]]
Category Load (0.2ms) SELECT "categories".* FROM "categories" WHERE "categories"."id" = $1 LIMIT $2 [["id", 18], ["LIMIT", 1]]
SQL (0.4ms) INSERT INTO "images" ("image", "category_id", "created_at", "updated_at", "user_id") VALUES ($1, $2, $3, $4, $5) RETURNING "id" [["image", "solnce-kosmos-merkuriy.jpg"], ["category_id", 18], ["created_at", "2018-01-30 12:33:26.945577"], ["updated_at", "2018-01-30 12:33:26.945577"], ["user_id", 22]]
(0.2ms) RELEASE SAVEPOINT active_record_2
Redirected to http://127.0.0.1:38226/en/categories/test/12
Completed 200 OK in 22ms (ActiveRecord: 1.6ms)
Started GET "/en/categories/test/12" for 127.0.0.1 at 2018-01-30 14:33:26 +0200
Processing by ImagesController#show as HTML
Parameters: {"locale"=>"en", "id"=>"test", "image_id"=>"12"}
User Load (0.6ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2 [["id", 22], ["LIMIT", 1]]
(0.1ms) SAVEPOINT active_record_2
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2 [["id", 22], ["LIMIT", 1]]
SQL (0.3ms) INSERT INTO "user_actions" ("user_id", "action_type", "url", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5) RETURNING "id" [["user_id", 22], ["action_type", "navigation"], ["url", "http://127.0.0.1:38226/en/categories/test/12"], ["created_at", "2018-01-30 12:33:26.966397"], ["updated_at", "2018-01-30 12:33:26.966397"]]
(0.1ms) RELEASE SAVEPOINT active_record_2
Category Load (0.1ms) SELECT "categories".* FROM "categories" WHERE "categories"."slug" = $1 LIMIT $2 [["slug", "test"], ["LIMIT", 1]]
Image Load (0.2ms) SELECT "images".* FROM "images" WHERE "images"."category_id" = $1 AND "images"."id" = $2 LIMIT $3 [["category_id", 18], ["id", 12], ["LIMIT", 1]]
Like Load (0.2ms) SELECT "likes".* FROM "likes" WHERE "likes"."image_id" = $1 AND "likes"."user_id" = $2 LIMIT $3 [["image_id", 12], ["user_id", 22], ["LIMIT", 1]]
Rendering images/show.html.haml within layouts/application
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2 [["id", 22], ["LIMIT", 1]]
(0.3ms) SELECT COUNT(*) FROM "comments" WHERE "comments"."image_id" = $1 [["image_id", 12]]
Like Load (0.2ms) SELECT "likes".* FROM "likes" WHERE "likes"."user_id" = $1 AND "likes"."image_id" = 12 LIMIT $2 [["user_id", 22], ["LIMIT", 1]]
(0.3ms) SELECT COUNT(*) FROM "likes" WHERE "likes"."image_id" = $1 [["image_id", 12]]
Rendered likes/_like.html.haml (3.2ms)
Rendered likes/_like_form.html.haml (7.3ms)
Rendered comments/_comments.html.haml (2.7ms)
Rendered comments/_comments_container.html.haml (5.1ms)
Rendered images/show.html.haml within layouts/application (25.6ms)
Category Load (1.3ms) SELECT DISTINCT categories.*, COUNT(images.*) AS images_count, categories.*, COUNT(likes.*) AS likes_count, categories.*, COUNT(comments.*) AS comments_count FROM "categories" LEFT OUTER JOIN "images" ON "images"."category_id" = "categories"."id" LEFT OUTER JOIN "images" "images_categories_join" ON "images_categories_join"."category_id" = "categories"."id" LEFT OUTER JOIN "likes" ON "likes"."image_id" = "images_categories_join"."id" LEFT OUTER JOIN "images" "images_categories_join_2" ON "images_categories_join_2"."category_id" = "categories"."id" LEFT OUTER JOIN "comments" ON "comments"."image_id" = "images_categories_join_2"."id" GROUP BY categories.id ORDER BY images_count DESC, likes_count DESC, comments_count DESC LIMIT $1 [["LIMIT", 5]]
Rendered layouts/_header.html.haml (4.6ms)
Rendered layouts/_footer.haml (0.1ms)
Completed 200 OK in 43ms (Views: 30.0ms | ActiveRecord: 4.1ms)
Started GET "/home/Anton-S/RubymineProjects/rails_projects/gallery/spec/support/uploads/image/image/12/solnce-kosmos-merkuriy.jpg" for 127.0.0.1 at 2018-01-30 14:33:27 +0200
(0.2ms) ROLLBACK TO SAVEPOINT active_record_1
(0.1ms) ROLLBACK
(0.1ms) BEGIN
(0.1ms) COMMIT
(0.0ms) BEGIN
(0.0ms) SAVEPOINT active_record_1
(0.1ms) SAVEPOINT active_record_2

据我了解,图片已成功上传。但是我仍然得到这个错误

Failure/Error: raise ActionController::RoutingError, "No route matches [#{env['REQUEST_METHOD']}] #{env['PATH_INFO'].inspect}"

ActionController::RoutingError:
No route matches [GET] "/home/Anton-S/RubymineProjects/rails_projects/gallery/spec/support/uploads/image/image/12/solnce-kosmos-merkuriy.jpg"

UPDATE 2

不幸的是,我找到的唯一解决方案是设置/config/environments/test.rb

config.action_dispatch.show_exceptions = true

但我仍然认为有更好的解决方案。

最佳答案

因此,从日志中,我们可以看到文件正在成功上传。

问题是当显示页面呈现时,图像被添加到 HTML 中,其 URL 类似于 '/home/Anton-S/RubymineProjects/rails_projects/gallery/spec/support/uploads/image/image/12/solnce-kosmos-merkuriy.jpg' 这将不起作用,因为 Rails 应用程序不会响应应用程序根目录中 public 目录之外的随机文件。这样做将是一个巨大的安全问题。最简单的解决方案是将图像存储到 public 目录中,以便 Rails 应用程序将它们作为静态 Assets 提供。类似的东西

  def cache_dir
"public/test/uploads/tmp"
end

def store_dir
"public/test/uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end

注意:我还评论了您对 have_current_path 匹配器的使用。

关于ruby-on-rails - capybara 上传图片问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48499129/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com