4

The vast majority of my cucumber features require the user to be logged in. However I don't really need to test the login functionality for every single test. I'm currently using Devise for my authentication.

I'm looking for a way to sign a user in with devise, without filling out the sign in form. Is there anyway to do this? I would prefer to not have to use the sign in action for every test.

4

2 回答 2

2

No, there is no way. In the documentation, with regard to the sign_in @user and sign_out @user helper methods, it says:

These helpers are not going to work for integration tests driven by Capybara or Webrat. They are meant to be used with functional tests only. Instead, fill in the form or explicitly set the user in session

As you said yourself, it is probably cleanest to do it with a before :each block. I like to structure it like the following:

context "login necessary" do
  # Before block
  before do
    visit new_user_session_path
    fill_in "Email", with: "test@test.com"
    fill_in "Password", with: "password"
    click_button "Login"
    assert_contain "You logged in successfully."
  end

  # Actual tests that require the user to be logged in
  it "does everything correctly" do
    # ...
  end
end

context "login not necessary" do
  it "does stuff" do
    # code
  end
end

I found this to be quite useful, since if I change authentication rules (i.e. whether or not the user has to be logged in for a specific path) I can just take the whole test and move it into the other description block, without changing any more code.

于 2013-01-31T23:02:21.070 回答
0

Generally, you should always test through the interface. But I think this is an acceptable exception.

I'm using devise with capybara with rspec but it should work for you too.

In a helper I have this:

module LoginHelper
  def login_as(user)
    super(user, :scope => :user, :run_callbacks => false)
  end
end

RSpec.configure do |config|
  config.include Warden::Test::Helpers, :type => :feature
  config.include LoginHelper, :type => :feature

  config.before :each, :type => :feature do
    Warden.test_mode!
  end

  config.after :each, :type => :feature do
    Warden.test_reset!
  end
end

Then in the feature:

  background do
    login_as(user)
    visit root_path
  end

Also see:
How to Stub out Warden/Devise with Rspec in Capybara test

于 2013-02-01T02:48:11.663 回答