What to test, how to test it and what to think about when load testing or stress testing your web application.
Testing a web application is very different from testing a web server. With an application you need to ensure you test the full stack, including the "heaviest" workloads. By examples these can include:
These operations are interactive, dynamic content. They typically are generated by a language like PHP, and often require a SQL database interaction. These are the common bottlenecks in a modern web application. Server load testing is very different, and has to do with raw requests per second from the web server itself, e.g. Nginx, Apache, etc.
You want to ensure your load testing attacks all the critical components of your application. Typically, this is three things:
In developing this strategy you'll want to determine the average wait time of a user of your service. Typically, a user waits on average between 5 and 9 seconds between webpages. So for each user we simulate we now know 1 dynamic page per 5-9 seconds.
After that, we want to gauge how many static content items are returned by your average webpage. Browse a few with Chrome or Firefox Developer tools open and watch the bottom bar for the total requests per page, as seen in this screenshot:
As you can see above, we requested 19 objects. However, in our case many of those are not hosted on our system as we use a CDN. You can look at the domain to work out how many items hit your site. Lets assume that on average its 10 static content items (stylesheets, CSS, fonts, images).
The final component is to ensure that the dynamic pages you are visiting are causing database load. For example, make sure you are logging in. Adding items to carts. Searching, opening blog posts, etc. In total our plan has led to these decisions:
LoadForge gives you the opportunity to design tests to suit your needs, like we've described above. We'll use LoadForge in this example, but you could also use another tool.
We can now write our LoadForge test, which we will execute against our website we've defined above. We'll start by defining just the basics - the website to run it against, and that we'll start with 500 simultaneous users. Remember that with our 5-9 seconds wait time decision that will be around 500/7 = 71 per second.
As you can see above that is defined very easily. The next step is where we can customize, defining the locustfile. We'll show you our complete one, and then break it down:
from locust import HttpUser, task, between class QuickstartUser(HttpUser): wait_time = between(5, 9) @task(1) def dynamic_page(self): self.client.get("/") @task(3) def static_content(self): self.client.get("/images/logo.png") self.client.get("/css/app.css") self.client.get("/js/app.js")
Let's break this down, it's quite similar to our default template, and if you want advanced uses check out our documentation.
As you can see we've defined wait_time as between(5, 9) - between 5 and 9 seconds as discussed above. Next we have the dynamic_page test, which is fetching simply /. We could add additional ones here as well.
Next up, @task(3) says to do this 3x as much as @task(1). We're using this to do the 3 static gets, to get to 9 static gets per 1 dynamic get.
Interpreting the results of your test are as important as running the test, if not more. Continue this on our reading load test results guide.