How to Script and Test Login / Logout for Load Testing
Scalability-wise, authentication is one of the most critical functions in a web application. Why? For most non-trivial web applications, the majority of their functionality requires prior authentication. The implication here is that the scalability of the system’s authentication provides a hard-ceiling on your website’s scalability. If your users can’t login, they can’t get to your website’s other functionality.
What is an authentication script in the context of load testing? Very simply, it is a targeted script that logs in and logs out of your web application. The authentication script simulates a portion of the load the application experiences during normal usage.
There are two main purposes we recommend creating a script like this for:
- To stress test and benchmark your authentications scalability in-isolation. By knowing your authentication system’s limits, you can plan for capacity and be assured that in a larger test, authentication won’t be the bottleneck.
- As part of a larger, real-world scenario test, the login script can represent the load demands that normal users login in and out will cause.
Testing a website’s authentication performance correctly can be challenging. What are the key considerations when scripting for authentication?
In Isolation
To isolate authentication functionality, a login script should touch as few other pages as possible. If any extraneous pages are included, they should be chosen to be the least impactful from a resource perspective. It is common for web applications to redirect to the last page a user was on before they logged in. In this case, the page should be a fairly simple page, with as little on-page business logic or database calls as possible.
On the same token, scripts other than the login script should touch the login functionality as seldomly as possible, and should, ideally, not be logging in and out with each iteration. Scripts that login and out on each iteration can overweight and overstress the authentication components. If your application’s authentication is more scalable than other functional areas, this won’t be a problem. However, if authentication is less scalable than other functional areas of your website, your test may fail, but in the real-world, your application would be fine!
Isolating the authentication functionality achieves several things
- The scalability of the authentication components can be tested and tuned directly.
- The proportional load on the components can be tuned proportionately for real-world scenarios.
- False negatives due to overstressing authentication components can be avoided.
For many sites, the login script (in pseudocode) is simply
visit /login
post credentials to /login,
verify landing page is in authenticated state
visit /logout
verify page is in unauthenticated state
Verification
An authentication script should verify that the landing page post-login is in an authenticated state.
It is possible to that the login failed, or the site is displaying an error. The easiest way to accomplish this for most sites is to check the rendered HTML for the username if it is displayed. This isn’t always possible, but provides a quick and easy check. Another alternative it so request and verify content that is only present for a user who is authenticated.
Logout
After logging out, the post-logout page should be checked to confirm the username is absent.
Databanking and Caching
At the application-level, applications often cache recent users. Because of this, to make an authentication script’s load characteristics realistic, it needs to authenticate with many different users. So when creating a login/logout script, it must be databanked (aka data-driven) with enough records to simulate normal usage and prevent the application from surviving off cached records, which would skew your results with an overly positive performance result.
If the users resources are cached, they may have response times that won’t align with what will be seen in the real-world.
Think Time
When testing your login, you should account for think-time. Running a test without think-time, or with a delay of zero and measuring only throughput can give a false-positive. Here’s why–behind the scenes, many webservers hold a connection open per-user. If you run a small number of users very quickly, you’ll exercise the throughput of your website, but you won’t be testing your concurrency properly. This is especially an issue with server keepalives–by holding open a server connection, user’s get a faster response. However, connections are finite, and if your test doesn’t hold as many connections open as real world users will, you might get a false-positive load testing result, when your application would fail in the real-world.
To continue exploring this topic, learn more in our article about How to Load Test a Website with Authentication