I'm building a Rails 3 app using Devise, with Capybara for UI testing. The following test is failing:
class AuthenticationTest < ActionController::IntegrationTest
def setup
@user = User.create!(:email => 'test@example.com',
:password => 'testtest',
:password_confirmation => 'testtest')
@user.save!
Capybara.reset_sessions!
end
test "sign_in" do
# this proves the user exists in the database ...
assert_equal 1, User.count
assert_equal 'test@example.com', User.first.email
# ... but we still can't log in ...
visit '/users/sign_in'
assert page.has_content?('Sign in')
fill_in :user_email, :with => 'test@example.com'
fill_in :user_password, :with => 'testtest'
click_button('user_submit')
# ... because this test fails
assert page.has_content?('Signed in successfully.')
end
end
... but I have no idea why. As you can see from the code, the user is being created in the database; I'm using the same approach to create the user as I did in seeds.rb.
If I run the test through the debugger, I can see the user in the database and verify that the page is loading. But still the authentication fails; I can verify this because if I change the assertion to test for the failure case, the test passes:
# verify that the authentication actually failed
assert page.has_content?('Invalid email or password.')
I'm used to Rails 2, & using Selenium for this sort of testing, so I suspect I'm doing something daft. Could someone please point me in the right direction here?
I was having the same issue and found a thread with a solution:
RSpec.configure do |config|
config.use_transactional_fixtures = false
config.before(:suite) do
DatabaseCleaner.strategy = :truncation
end
config.before(:each) do
DatabaseCleaner.start
end
config.after(:each) do
DatabaseCleaner.clean
end
end
For the DatabaseCleaner stuff to work you'll need to include the database_cleaner
gem. If you haven't used it before, you may need to rake db:test:prepare
before rerunning your tests. I hope this works for you, too!
I've run into a similar problem before. Setting the password directly has some weird effects because it's supposed to be encrypted and stored with a salt--sometimes it works for me and other times it doesn't. I have a hard time remembering which specific cases were problematic. I'd recommend the following, in this order (for simplicity)
- Verify that the password field is getting filled in properly and passed as the right param (not necessary if you're using Devise's autogenerated view and haven't touched it)
- if your site can run in development mode (i.e. no log in bugs), then just boot it up and log in manually
- If not, insert
debugger
as the first line in your sessions_controller
. Then check params
and make sure the password is correct and in params[:user][:password]
.
If you didn't override Devise's sessions_controller
, then you can find your Devise path with bundle show devise
. Then look for the create
action within (devise path)/app/controllers/devise/sessions_controller.rb
- Change your test setup to create a user through the web interface, to ensure the password gets set properly, then try running your test again
I had the same issue with a setup fairly similar to yours. In my case, switching to ActiveRecord sessions in the initializer solved the problem.
Additionally, make sure you call @user.skip_confirmation! if you are using the "confirmable" module in devise.