Handle authenticated users when using Behat and Mink with Laravel 4Categories: Laravel, Mink, Behat, Session
Behat is a great tool for testing your Laravel application. At Label305 we use Behat and Mink extensively to test several applications. But when using Mink drivers like Selenium to test your application it can take ages for all tests to finish. With the simple trick described below you can speedup your tests by creating a logged in state before the browser/client is fired up.
Preparing Application State
behat it is smart to create application state when evaluating the
Given ... statements without using the browser. So for example by filling the database. This way you prevent testing stuff in the browser twice.
When we just started out with Behat we created application state for our new scenarios by calling parts of previously implemented scenarios. So if the scenario required a registered user, the test would actualy go to the registration form, fill it out and register the user. This can add up when you have 100+ scenario’s and most of them require a registered user.
Implementing a step like
Given there is a user with email "email@example.com" by populating the database is not that difficult of course. Just execute a couple of database queries.
When using Eloquent models to query the database you need to have a booted application container. You can make sure this has happened by adding the following method to your
It is important that the application running from
behat is using the right environment. Make sure
detectEnvironment() is setup to give the application a seperate environment. I’ve used
getenv() in this example.
Now we will look at the step
Given I am logged in as "firstname.lastname@example.org". When you are using Behat without an external server this is as simple as
In our case, the Behat process is seperated from the server because we wanted to use Selenium. However, we want the user to be logged in without having to fill out the login for every scenario (which takes time, especialy when this is done 100+ times). How to accomplish this? By using something that looks like session hijacking, but without the hacking part.
Authentication state is stored to the session and a user specifies which session he/she is using by providing a cookie. We wanted to create a session in the Behat process and let Selenium use that session to let it execute its steps. So we gave Selenium a cookie, omnomnom.
This does not work out of the box, however. You will have to make sure that session data can be shared between the behat and server process. So you can’t use the
array session provider. Using the
file provider should be fine, and make sure both the environment of the server and Behat are using that setting.
Now for the tricky part. The
Illuminate\Session\SessionServiceProvider has a method
setupDefaultDriver() which makes sure the application always uses the
array session provider when executing the application from the command line. So we need to extend the
Illuminate\Session\SessionServiceProvider and create our own service provider and swap them out in the
config/app.php. But in order to keep things clean, make sure this only happens in the
behat environment (setup above in the
So now your all set up to start using Selenium, Goutte or the other decoupled Mink drivers and keep your tests running relatively fast.