質問

Cucumber+WebratからCucumber+Capybaraに切り替えたばかりで、CapybaraのURLにコンテンツをどのように投稿できるのか疑問に思っています。

キュウリ+ウェブラットでは、ステップを踏むことができました。

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 Methodは単一のパラメーターのみを取得します。リクエストメソッドは常に取得します。

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 アプリの最後のドキュメントを削除します。

カピバラ 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 (たとえば、PolterGeistはそうではありません)、これを行うことができます。

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

ただし、このリクエストは新しいセッションで発生するため、 response それを主張するオブジェクト。

他の場所で述べられているように、カピバラのテストでは、ユーザーと同じようにフォームを送信して投稿をしたいと考えています。上記を使用して、別のセッション(WebSocketsを介して)で投稿が発生した場合にユーザーに何が起こるかをテストするため、フォームはそれをカットしませんでした。

ドキュメント:

答えはすでに受け入れられていることは知っていますが、更新された答えを提供したいと思います。これがテクニックです アンソニー・エデンコーリー・ヘインズ ラックを通過します:: Cucumber's Worldオブジェクトへのテスト:

キュウリとラックを使用してAPIを休憩します::テスト

この手法により、ステップ定義内でPOSTリクエストを直接送信することができました。ステップの定義を書いている間、ラックを学習することは非常に役立ちました::独自の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のラックテスト。同じテストスイート内で一緒に使用できます。

スペックヘルパーに以下を追加すると、アクセスできます get, post およびその他のラックテスト方法:

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

ラックテスト仕様をに配置する必要がある場合があります spec/requests フォルダ。

RSPEC 3+を使用するアプリケーションを使用すると、CapybaraでHTTP POSTリクエストを作成したくありません。 Capybaraは、ユーザーの動作をエミュレートし、結果として生じるJSの動作とページコンテンツを受け入れるためです。エンドユーザーは、アプリケーション内のリソースのHTTP投稿リクエストをフォームしません。ユーザーはボタンをクリックし、Ajaxリンクをクリックし、nドロップ要素をドラッグし、Webフォームを提出します。

チェックアウト このブログ投稿 Capybaraおよびその他のHTTPメソッドについて。著者は次の主張をします。

GET、投稿、応答などの方法についての言及を見ましたか?いいえ?それは、それらがカピバラに存在しないからです。これについて非常に明確にしましょう... Capybaraは、APIのテストに適したライブラリではありません。そこにあなたはそれを持っています。 CapybaraでAPIをテストしないでください。それはそれのために設計されていませんでした。

したがって、APIを開発するかどうかにかかわらず、明示的なHTTP POSTリクエストを作成する必要があり、HTML要素と何らかのイベント(クリック、ドラッグ、選択、フォーカスなど)が含まれない場合は、カピバラでテスト。ボタンをクリックして同じ機能をテストできる場合は、Capybaraを使用してください。

あなたが望んでいるのはおそらくです RSPECリクエスト仕様. 。ここで作ることができます post 呼び出し、およびその他のHTTPメソッドも同様に、応答に対する期待を主張します。また、副作用やリクエストと応答の間に発生するその他の動作に関して期待を主張するために、nスタブオブジェクトと方法をock笑することもできます。

# 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