Apr 20th, 2011, 11:02 AM
Mocking out authentication for functional tests when using Spring Security
I have a suite of Selenium-driven functional tests for a web application I'm developing. I've recently integrated with Spring Security as a means of handling authentication. All of my functional tests now fail, naturally, given that every request is now taken to a login screen rather than the page that was originally requested.
There are many ways I can go about tackling this problem, of course, but none of them seem particularly appealing. Hard coding in dummy credentials into my testing code and then logging in as part of every test case seems ugly, fragile, and insecure. Adding in some kind of application level switch to disable authentication for test purposes likewise seems like a bad idea- any chance that security could be disabled in production is undesirable.
Surely I am not the first person to encounter this issue. What is the best means of handling authentication when writing functional tests for an application using Spring Security?
Apr 20th, 2011, 08:53 PM
Personally, I like to use Geb (which uses WebDriver behind the scenes) and Spock to run my functional tests. Spock offers the @Stepwise annotation which ensures your tests are executed in the order they are declared. This means that you can login once at the beginning and execute numerous steps without needing to login again (just as a real user does). You can find an example of how to do this in Spring Security's CAS Sample application in master. One of the disadvantages to using @Stepwise is the tests can't be run in parallel. This means that you will likely want to find a balance between how many times you need to authenticate and how many tests you require to be ran in a particular order.
Originally Posted by ecrane
The tests above use a hard coded user which, as you pointed out, in most situations is a bad idea. Typically in the real world I have tests use a default username / password of a user that exists in my dev environment to run my tests against. This is acceptable because the dev deployment is only accessible behind company walls. You could allow the username / password to be overridden in some fashion (i.e. System Properties and Springs PropertyPlaceholderConfigurer could do the trick) to support other environments. Another possibility is that you setup your tests to automatically add a user at startup and remove the user when complete. Of course at that point you need to ensure you secure the credentials used to add the user (i.e. database username/password).
Tags for this Thread