In the Locust introductory article, I was able to perform load testing for the time being, but this article is for those who want to know more.
This article is http://docs.locust.io/en/latest/ This is a summary of the information listed in. The sample code is also from the same site.
The execution interval of each task is a random value between min_wait and max_wait.
Real users don't run the API all the time. If it is a blog site, it will take time to see the text, and even if it is a game application, there will be an interval between APIs and API execution depending on the content. If you can predict user behavior to some extent, setting min_wait and max_wait to appropriate values will result in a load closer to actual operation.
The default is min_wait = 500, max_wait = 1500. (Unit is milliseconds)
from locust import Locust, TaskSet, task
class MyTaskSet(TaskSet):
@task
def my_task(self):
print "executing my_task"
class MyLocust(Locust):
task_set = MyTaskSet
min_wait = 5000
max_wait = 15000
Override when setting min_wait and max_wait. By the way
self.wait()
Uses min_wait and max_wait for random time weighting. I can't divide it into task functions, but I don't want them to be executed continuously without waiting time I think it can be used for user registration tests, etc.
It is unlikely that all pages of websites and web apps will be viewed and visited equally. The top page is the most, and the terms of use etc. will not be viewed very often.
This allows tasks to be weighted for execution.
class WebUserLocust(Locust):
weight = 3
....
class MobileUserLocust(Locust):
weight = 1
....
With the above configuration, WebUserLocust runs 3 times more often than MobileUserLocust.
If the Locust class is a flock of locusts, the TaskSet class is the locust brain. Is it like the Locust class determines the overall behavior and the TaskSet class determines how each works? (I can't convey it well because my Japanese translation ability is low ...)
You can explicitly declare a task function by adding a task decorator to the member function in the TaskSet class.
from locust import Locust, TaskSet, task
class MyTaskSet(TaskSet):
@task
def my_task(self):
print "Locust instance (%r) executing my_task" % (self.locust)
class MyLocust(Locust):
task_set = MyTaskSet
On the contrary, it seems that it will be used such as implementing a common processing function in the class without attaching a task decorator.
In addition, this task decorator can set the above weighting by argument.
from locust import Locust, TaskSet, task
class MyTaskSet(TaskSet):
min_wait = 5000
max_wait = 15000
@task(3)
def task1(self):
pass
@task(6)
def task2(self):
pass
class MyLocust(Locust):
task_set = MyTaskSet
The difference from weighting in the Locust class is whether it is module-based or function-based. (In terms of website, page unit or action unit within page)
Websites and web apps often have hierarchized pages. By nesting the task set accordingly, it is more tailored to the actual user behavior. You can write a scenario. Also, by dividing the task set like a module, various combinations can be made. You can implement the scenario with minimal code.
class ForumPage(TaskSet):
@task(20)
def read_thread(self):
pass
@task(1)
def new_thread(self):
pass
@task(5)
def stop(self):
self.interrupt()
class UserBehaviour(TaskSet):
tasks = {ForumPage:10}
@task
def index(self):
pass
As the scale of the application increases, so does the API, so consider maintainability. It's a good idea to divide your task set as much as possible.
interrupt( ) In the above code, the stop () function is executing self.interruput (). interruput () exits the current task set and reassigns tasks to the higher task set It is a function to make. If you don't call this, the Locust instance will endlessly do the tasks in the ForumPage. Keep running. Since the actual user should move various pages, interrupt function as appropriate It's important to do it.
Although it is quite important content http://docs.locust.io/en/latest/ If you haven't read, it's hard to come up with the idea of explicitly executing interrupt () ...
Decorators can also be applied to classes, so you can write them like this:
class MyTaskSet(TaskSet):
@task
class SubTaskSet(TaskSet):
@task
def my_task(self):
pass
I just want to find a good way to write it because blindly nesting it only complicates it.
on_start on_start () is called when the task set starts. HTTP headers required for the API should be set here.
I think that HTTP Locust etc. are introduced in the introductory article below, so I will omit them. There is a lot of other useful information http://docs.locust.io/en/latest/ I recommend you to read it. (English only) Also, the source code of Locust is on github, so it's interesting to take a look. https://github.com/locustio