Cucumber test redirect
Have found some advice: http://openmonkey.com/articles/2009/03/cucumber-steps-for-testing-page-urls-and-redirects
I have added the above methods to my web steps definitons, have written my feature, ran it and got an error about nil objects. After some investigation, I have noticed, I ha开发者_JAVA百科ve no response and request objects, they are nil
From web_steps.rb:
Then /^I should be on the (.+?) page$/ do |page_name|
request.request_uri.should == send("#{page_name.downcase.gsub(' ','_')}_path")
response.should be_success
end
Then /^I should be redirected to the (.+?) page$/ do |page_name|
request.headers['HTTP_REFERER'].should_not be_nil
request.headers['HTTP_REFERER'].should_not == request.request_uri
Then "I should be on the #{page_name} page"
end
The request and response objects are nil, why ?
Are you using WebRat or Capybara as your driver within Cucumber? You can tell by looking at features/support/env.rb
. I'm using Capybara, so mine includes these lines:
require 'capybara/rails'
require 'capybara/cucumber'
require 'capybara/session'
The default used to be WebRat but switched recently to Capybara, so a lot of the code from older examples on the web doesn't work properly. Assuming you're using Capybara too...
request.request_uri - You want current_url instead. It returns the full URL of the page your driver is on. This is less useful than getting just the path, so I use this helper:
def current_path
URI.parse(current_url).path
end
response.should be_success - One of the biggest frustrations with working with Capybara (and to a certain extent, Cucumber) is that it is downright zealous about only interacting with what the user can see. You can't test for response codes using Capybara. Instead, you should test user-visible responses. Redirects are easy to test; just assert what page you should be on. 403s are a little tricker. In my application, that's a page where the title is "Access Denied," so I just test for that:
within('head title') { page.should_not have_content('Access Denied') }
Here's how I'd write a scenario to test a link that is supposed to redirect sometimes and not supposed to redirect at other times:
Scenario: It redirects
Given it should redirect
When I click "sometimes redirecting link"
Then I should be on the "redirected_to" page
Scenario: It does not redirect
Given it shouldn't redirect
When I click "sometimes redirecting link"
Then <assert about what should have happened>
You can test the response code like this:
Then /^I should get a response with status (\d+)$/ do |status|
page.driver.status_code.should == status.to_i
end
It does sometime make sense to use cucumber for this kinda thing, but its best avoided.
Can you not use a controller spec?
I see this is an old question, but I want to add my answer, may be someone find it helpful. Cucumber is an end-to-end acceptance (or integration as many call it) test framework, it means that when using it, you should not care about the intermediate states, but the beginning of a request (i.e. from where the request is initiated: click on a button or link, navigation from the address bar and so on), and the final result (i.e. what the user will see on the page when the load completed).
What you need here is a Controller spec, that is better to be specified by Rspec, which will give you better access to intermediates states in the action level. An example can be:
describe AController do
#specify the action where you expect a redirect
describe 'GET action' do # or POST action
get :action # or post with post params if the request expected to be a form submition
expect(response).to be_redirect
end
end
Generally it is not recommended to test current url, response codes and headers in cucumber. I would advice you to write more low level test for this purpose: functional controller test or request specs
To answer your question:
Then /^I should be on the (.+?) page$/ do |page_name|
expect(current_url).to eq send("#{page_name.downcase.gsub(' ','_')}_path")
end
Then /^I should be redirected to the (.+?) page$/ do |page_name|
expect(current_url).to eq send("#{page_name.downcase.gsub(' ','_')}_path")
end
Capybara performs redirects automatically
I just had to test the same thing and came up with the following for Cabybara 1.1.2
Then /^I should be on the (.*) page$/ do |page_name|
object = instance_variable_get("@#{page_name}")
page.current_path.should == send("#{page_name.downcase.gsub(' ','_')}_path", object)
page.status_code.should == 200
end
Then /^I should be redirected to the (.*) page$/ do |page_name|
page.driver.request.env['HTTP_REFERER'].should_not be_nil
page.driver.request.env['HTTP_REFERER'].should_not == page.current_url
step %Q(I should be on the #{page_name} page)
end
精彩评论