Вопрос

Только что переключился с Cucumber + Webrat на Cucumber + Capybara, и мне интересно, как вы можете ПУБЛИКОВАТЬ контент по URL в Capybara.

В Cucumber + Webrat я смог сделать шаг вперед:

When /^I send "([^\"]*)" to "([^\"]*)"$/ do |file, project|
  proj = Project.find(:first, :conditions => "name='#{project}'")
  f = File.new(File.join(::Rails.root.to_s, file))
  visit "project/" + proj.id.to_s + "/upload",
        :post, {:upload_path => File.join(::Rails.root.to_s, file)}
end

Однако в документации Capybara упоминается:

Метод visit принимает только один параметр, метод request - всегда GET.всегда GET.

Как мне изменить свой шаг, чтобы Cucumber + Capybara отправлял ПУБЛИКАЦИЮ по URL-адресу?

Это было полезно?

Решение

Совсем недавно я нашел Это отличное сообщение в блоге. Отказ Который отлично подходит для таких случаев, как Тони и где вы действительно хотеть Чтобы выложить что-то в своем выставке:

Для моего случая это стало:

def send_log(file, project)
  proj = Project.find(:first, :conditions => "name='#{project}'")
  f = File.new(File.join(::Rails.root.to_s, file))
  page.driver.post("projects/" + proj.id.to_s + "/log?upload_path=" + f.to_path)
  page.driver.status_code.should eql 200
end

Другие советы

Вы могли бы сделать это:

rack_test_session_wrapper = Capybara.current_session.driver
rack_test_session_wrapper.submit :post, your_path, nil
  • Вы можете заменить :post который любой метод, который вы заботитесь о, например, :put или :delete.
  • Заменять your_path с траекторией рельсов, например, rack_test_session_wrapper.submit :delete, document_path(Document.last), nil удалил бы последний документ в моем приложении.

Capybara's. visit Только получает запросы. Это по дизайну.

Для пользователя, чтобы выполнить POST, он должен нажать кнопку или отправить форму. Нет другого способа сделать это с браузером.

Правильный способ проверить это поведение было бы:

visit "project/:id/edit" # This will only GET
attach_file "photo", File.open('cute_photo.jpg')
click_button 'Upload' # This will POST

Если вы хотите проверить API, я рекомендую использовать spec/request вместо огурца, но это только я.

Если у вашего водителя нет post (Полтергейст не так, например), вы можете сделать это:

session = ActionDispatch::Integration::Session.new(Rails.application)
response = session.post("/mypath", my_params: "go_here")

Но обратите внимание, что этот запрос происходит на новой сессии, поэтому вам придется пройти через response объект, чтобы утверждать на нем.

Как было сказано в другом месте, в тесте Capybara вы обычно хотите делать сообщения, отправив форму, как пользователь, будет. Я использовал вышесказанное для проверки того, что происходит с пользователем, если пост происходит на другом сеансе (через WebSockets), поэтому форма не будет сокращена.

Документы:

Я знаю, что ответ уже был принят, но я хотел бы предоставить обновленный ответ. Вот технику от Энтони Эдем и Кори Хейнс который проходит стойку :: Test к World Object Cucumber:

Тестирование API для отдыха с огурцом и стойкой :: Test

С этой техникой я смог напрямую отправить запросы пост на определениях шага. При написании определений шага это было чрезвычайно полезно для изучения стойки :: Test API от его собственного спецификация.

# feature
  Scenario: create resource from one time request
    Given I am an admin
    When I make an authenticated request for a new resource
    Then I am redirected  
    And I see the message "Resource successfully created" 

# step definitions using Rack::Test
When /^I make an authenticated request for a new resource$/ do
  post resources_path, :auth_token => @admin.authentication_token
  follow_redirect!
end

Then /^I am redirected$/ do
  last_response.should_not be_redirect
  last_request.env["HTTP_REFERER"].should include(resources_path)
end

Then /^I see the message "([^"]*)"$/ do |msg|
  last_response.body.should include(msg)
end

Хотя, не точный ответ на вопрос, лучшее решение для меня было использовать Capybara для спецификации, которые моделируют взаимодействие пользователя (используя visit) и испытание в стойку для тестовых API, как запросы. Они могут быть использованы вместе в том же тестовом номере.

Добавление следующего к Spec Helper дает доступ к get, post И другие методы испытаний стойки:

RSpec.configure do |config|
  config.include Rack::Test::Methods

Вам может потребоваться поставить спецификации стойки в spec/requests папка.

В приложении, использующем RSpec 3 +, вы бы не захотели выполнять HTTP POST-запрос с помощью Capybara.Capybara предназначена для эмуляции поведения пользователя и принятия результирующего поведения JS и содержимого страницы.Конечный пользователь не формирует HTTP POST-запросы на ресурсы в вашем приложении, пользователь нажимает кнопки, переходит по ajax-ссылкам, перетаскивает элементы, отправляет веб-формы и т.д.

Проверьте это сообщение в блоге о Capybara и других HTTP-методах.Автор выдвигает следующее утверждение:

Видели ли вы какие-либо упоминания о таких методах, как get, post или response?Нет?Это потому, что у капибар их нет.Давайте внесем предельную ясность в этот вопрос...Capybara - это библиотека, не подходящая для тестирования API.Вот оно, в чем дело.Не тестируйте API-интерфейсы с помощью Capybara.Он не был предназначен для этого.

Итак, разрабатываете вы API или нет, если вам нужно сделать явный HTTP POST-запрос, и он не включает HTML-элемент и какое-либо событие (щелчок, перетаскивание, выбор, фокусировка, что угодно), то его не следует тестировать с помощью Capybara.Если вы можете протестировать ту же функцию, нажав на какую-нибудь кнопку, то используйте Capybara.

То, чего вы, вероятно, хотите, это Запрос спецификаций RSpec.Здесь вы можете сделать post вызывает, а также любой другой HTTP-метод и утверждает ожидания в отношении ответа.Вы также можете имитировать n объектов-заглушек и методов, чтобы утверждать ожидания в отношении побочных эффектов и другого поведения, которые происходят между вашим запросом и ответом.

# spec located in spec/requests/project_file_upload_spec.rb
require "rails_helper"

RSpec.describe "Project File Upload", type: :request do

  let(:project) { create(:project) }
  let(:file)    { File.new(File.join(::Rails.root.to_s, 'path/to/file.ext')) } # can probably extract this to a helper...

  it "accepts a file uploaded to a Project resource" do

    post "project/#{project.id}/upload", upload_path: file

    expect(response).to be_success
    expect(project.file?).to eq(true)
    # expect(project.file).not_to eq(nil)
    expect(response).to render_template(:show)
  end

end
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top