0

Locust is a load testing tool/framework that uses Python for writing such tests.

One feature it supports is the possibility to define weights for tasks:

import random
from locust import HttpUser, task, between

class TestUser(HttpUser):
    wait_time = between(3, 5)
    products = [
        "/damska-mestska-obuv-racia-lbtr230768?colorVariant=679225",
        "/detske-funkcni-triko-runno-ktsr294?colorVariant=683582"
    ]

    @task(1)
    def product_detail_page(self):        
        self.client.get(random.choice(TestUser.products))

    @task(2)
    def home_page(self):        
        self.client.get("/")

This example should mean, that home_page task will be executed twice as likely as product_detail_page task. This is one of the easiest examples I mostly picked from quick start page in the official documentation. And surely the results indicate this works as expected:

enter image description here

However, I can also use TaskSet classes like so:

import random
from locust import HttpUser, TaskSet, task, between

class TaskHomePage(TaskSet):
    
    @task
    def index(self):
        self.client.get("/")

class TaskProductPage(TaskSet):
    products = [
        "/damska-mestska-obuv-racia-lbtr230768?colorVariant=679225",
        "/detske-funkcni-triko-runno-ktsr294?colorVariant=683582"
    ]       
    
    @task
    def product(self):
        self.client.get(random.choice(TaskProductPage.products))    


class Tests(HttpUser):    
    wait_time = between(3, 5)
    
    tasks = {
        TaskHomePage: 2,
        TaskProductPage: 1
    }

Attribute tasks in Tests class can be a dict like I'm using it in the example, the values could be integers that again define the weights, so in this example I expect that tasks in TestHomePage will be executed twice as likely as tasks in the TaskProductPage. Official documentation talks about it here and here.

However, the results are not anywhere near "twice as likely":

enter image description here

This is ~ 3.7 times more likely. Why?

I can take it one step further and write:

import random
from locust import HttpUser, TaskSet, task, between

class TaskHomePage(TaskSet):
    
    @task
    def index(self):
        self.client.get("/")


class TaskProductPage(TaskSet):    
    
    @task(1)
    def product(self):
        self.client.get("/damska-mestska-obuv-racia-lbtr230768?colorVariant=679225") 

    @task(2)
    def product2(self):
        self.client.get("/detske-funkcni-triko-runno-ktsr294?colorVariant=683582")   


class Tests(HttpUser):
    wait_time = between(3, 5)

    tasks = {
        TaskHomePage: 2,
        TaskProductPage: 1
    }

I'd expect that:

  • tasks in TaskHomePage will be executed twice as likely as tasks in TaskProductPage
  • task product2 will be executed twice as likely as product

The results are:

enter image description here

That's not even close to either expectation.

That leaves me with a bitter taste about using weights. Is there something I'm doing wrong? How can I make it work? Is this feature reliable with more complex examples than just simple tasks within one class (the first example in my question)?

Also important:

  • I've also let some of these examples run for more than 10 minutes, and the numbers were still off, so it's perhaps not even a problem of small numbers; this is a screenshot for example 3 from the above code snippets: enter image description here
  • I didn't experience any errors and/or exceptions during my example runs, so this should not even be a problem of some of the endpoints failing/returning 500 or whatever bad.
  • I don't expect it to be exactly "twice as likely" in the sense of a=2b, but in my opinion, it should not be >2.5 as likely etc. That feels like too much even after rouding.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.