If you’re building an app that has user login functionality, you’ll at some point need to write some tests that log the user in before performing the test steps.
One approach I’ve seen is to have Capybara actually navigate to the sign in page,
fill_in the email and password fields, and hit submit. This works but, if you’re using Devise, it’s a little more complicated than necessary. There’s a better way.
The Devise docs have a pretty good solution. Just add this to
RSpec.configure do |config| config.include Warden::Test::Helpers end
Then, any place you need to log in, you can do
Log in before each test or log in once before all tests?
One of my readers, Justin K, wrote me with the following question:
If you use Capybara to do system tests, how do you handle authentication? Do you do the login step on each test or do you log in once and then just try and run all of your system level tests?
The answer is that I log in individually for each test.
The reason is that some of my tests require the user to be logged in, some of my tests require that the user is not logged in, and other tests require that some specific type of user (e.g. an admin user) is logged in.
I do often put my
login_as call in a
before block at the top of a test file to reduce duplication, but that doesn’t mean only once for that set of files. A common misconception is that a
before block will give a performance benefit by only running the code in the
before block once. This is not the case.
before is shorthand for
before(:each) and any code inside it will get run before each individual
it block. I never use
before(:all) inside of individual tests because I want each test case to be as isolated as possible.