Load Testing with Locust.io

(English below)

Lời dẫn

Trong bài viết này, mình sẽ giới thiệu về Locust – một công cụ hỗ trợ cho load testing được viết bằng Python cùng với nhiều tính năng khá thú vị mà mình hi vọng sẽ bổ ích với những anh / chị / bạn đang cân nhắc khi chọn lựa giải pháp cho việc kiểm thử độ chịu tải của hệ thống.

Giới thiệu

Locust được phát triển bởi  Carl Byström từ tháng 6 năm 2010 và sau đó được Jonatan Heyman tiếp tục phát triển từ tháng 1 năm 2011 và sau đó được ESN Social Software tiếp nhận và trở thành dự án mã nguồn mở trực thuộc công ty này.

Ý tưởng chính là tạo nên một công cụ hỗ trợ load testing với những test scenarios được viết bằng những dòng code thuần và có thể chạy phân tán một cách đơn giản. Và chúng ta có được Locust.

Note: Mã nguồn và một số ví dụ mọi người có thể tham khảo tại repo này

Bắt đầu với Locust

Cài đặt

Trước tiên, bạn cần cài đặt Python phiên bản 3.6 trở lên trên máy. Do Locust từ bản 0.8.1 sẽ chỉ hỗ trợ Python 3.6 và những bản về sau.

Cài đặt với pip (Khuyến khích cho việc sử dụng bản ổn định)

Cách đơn giản nhất để cài đặt Locust là sử dụng dòng lệnh pip:

pip install locustio

Sau khi cài đặt, chúng ta có thể kiểm tra phiên bản của Locust với dòng lệnh sau:

locust --version
[2018-08-26 17:03:14,986] ./INFO/stdout: Locust 0.8.1

Cài đặt phiên bản mới nhất từ repo GitHub

Phiên bản ổn định nhất hiện tại là 0.8.1 . Có một số tính năng mới được implemented trong bản 0.9.0, và nếu muốn thử sử dụng, bạn có thể tải trực tiếp source code của Locust từ repo chính và cài đặt thông qua Python Setup:

git clone https://github.com/locustio/locust.git
cd locust
python setup.py install

Chạy với Docker

Hiện tại vẫn chưa có Docker image chính thức cho Locust, nhưng bạn có thể pull  từ quay.io hay một số nguồn khác hoặc tự build hẳn một image riêng cho mình từ source code:

docker pull quay.io/honestbee/locust

Bắt tay vào viết Locustfile nào

OK. Chúng ta đã hoàn thành việc cài đặt Locust lên máy.

Trước khi bắt tay vào viết một đoạn test script để Locust chạy, ta có thể chuẩn bị một API server đơn giản, trong demo này mình sẽ dùng Flask:

pip install flask

Tạo một file và đặt tên tùy thích, ở đây mình đặt là main.py file:

# main.py
from flask import Flask, request, jsonify, app

import time
import random

app = Flask(__name__)

@app.route('/api', methods=['GET', 'POST'])
def index():
    if request.method =='GET':
        return jsonify(method=request.method)
    return jsonify(method=request.method,payload=request.json)

if __name__ == '__main__':
    app.run(host='0.0.0.0')

Đoạn code trên sẽ cho một API đơn giản trả về kiểu Request được gửi tới dưới dạng JSON. Ví dụ nếu bắn Request GET thì sẽ có response là { method:”GET”} được trả về. Còn nếu là một POST request với body là một dạng JSON thì sẽ trả về cả type of request lẫn nội dung của request.

Chạy API server với dòng lệnh dưới, đồng thời thì theo mặc định, Flask sẽ mở ở port 5000:

python main.py
* Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)

Okay, vậy là chúng ta đã có một cái “system under test”. Bắt đầu testing nào

Locust sẽ yêu cầu một file gọi là locustfile – nó đơn giản là một file định dạng Python (.py) – và trong file này phải chứa ít nhất một lớp Locust.

Một ví dụ đơn giản:

# locustfile.py
from locust import Locust, TaskSet, task

class UserTaskSet(TaskSet):              #3
    @task                                #4
    def my_task(self):
        print("executing my_task")

class User(Locust):                      #1
    task_set = UserTaskSet               #2 
    min_wait = 5000
    max_wait = 15000

Tại comment #1, chúng ta sẽ có lớp User được thừa hưởng từ lớp Locust. Có thể xem lớp Locust như một người dùng ảo để thực thi những tác vụ được ghi ở trong một tập các tác vụ.

Trong ví dụ ở trên, chúng ta xác định User với thuộc tính task_set chỉ vào một lớp là UserTaskSet (Tại comment #2, #3). Để khai báo các task cần thực hiện trong một TaskSet, chúng ta thêm @task decorator ở trước hàm my_task (#4)

Chạy script ở trên với lệnh locust. Theo mặc định, Locust sẽ tự tìm file với tên “locustfile”. Nếu bạn đặt tên file là một tên khác như tasks.py hay lamgido.py thì bạn có thể thêm cờ -f và tên file đi kèm.

locust -f lamgido.py

Sau khi chạy lệnh trên, bạn có thể vô giao diện Web tại http://localhost:8089/ giống hình bên dưới:

webui.PNG

Tại đây, bạn có thể đặt số lượng người dùng mong muốn, và bao nhiêu người dùng được “sinh ra” trong một giây. Nó cũng gần với khái niệm Ramp-up duration của JMeter, chỉ là tính theo một cách khác.

Hiện tại, với bộ script trên thì toàn bộ users của chúng ta chỉ có một task là in ra câu “executing my_task”. Đến lúc thêm thắt để chúng thực hiện một số tác vụ thực sự như giả lập những HTTP request, và để làm được điều đó thì chúng ta cần sử dụng HttpLocust – Một Locust class được implement để giả lập và quản lý những HTTP request / response.

Điều chỉnh đoạn script trên một xí:

# locustfile.py
from locust import HttpLocust, TaskSet, task 

class UserTaskSet(TaskSet):
    @task
    def get_index_task(self): 
        self.client.get("/api")    #3 

class User(HttpLocust):            #1 
    task_set = UserTaskSet 
    min_wait = 5000 
    max_wait = 15000
    host = "http://localhost:5000" #2

#1 Lớp User được thay thừa hưởng từ Locust sang HttpLocust

#2 Xác định Target host, ở đây là cái API server hồi nãy mình mới chạy

#3  Giá trị “self” ở đây đại diện cho một HttpLocust instance khi thực hiện tasks trong TaskSet đó, khi gọi nó sẽ trả về instance đang chạy, instance này có một thuộc tính là client (là một object dạng HttpSession) để chúng ta có thể gửi những request với định dạng khác nhau, và tùy chỉnh request đó.

Bây giờ chúng ta sẽ thêm một task mới gọi là “post_index_task” để gửi một POST request tới API server:

# locustfile.py
from locust import HttpLocust, TaskSet, task 

class UserTaskSet(TaskSet):
    @task
    def get_index_task(self): 
        self.client.get("/api", name="GET /api")

    @task
    def post_index_task(self):        # New task here
        payload = {'username': 'locmai'}
        self.client.post("/api", data=payload, name="POST /api")

class User(HttpLocust):
    task_set = UserTaskSet 
    min_wait = 5000 
    max_wait = 15000
    host = "http://localhost:5000"

Chạy thử đoạn script trên nào:

locust -f locustfile.py

Mở trình duyệt lên và chuyển tới http://localhost:8089/ , start test run:

starttesting.PNG

Thế là xong, chúng ta đã viết xong một đoạn script đơn giản thực hiện việc load test 1 API.

Giao diện Web

Locust cung cấp một giao diện Web để show một số thông tin cơ bản liên quan đến test được chạy. Với nó, bạn có thể dễ dàng customize giao diện và thêm một số endpoint hay tính năng mới nếu cần thiết, mình sẽ đề cập cách thức trong những bài viết sau một cách chi tiết hơn.

Trên thanh navigation sẽ có một số thứ như Target host, tình trạng của các virtual users, số lượng virtual users đã được “sinh ra” và có thể điều chỉnh lại số lượng này, RPS và failure rate. Ngoài ra thì bạn có thể Stop, start new test với Reset lại hết thông số nếu cần.

starttesting.PNG

Ở khu vực chính, trên tab Statistic sẽ có một table hiển thị các thông tin cơ bản của một cái load test

Bên tab Charts là một vài biểu đồ line đơn giản. Có thể gọi là vừa đủ. charts.PNG

Tab Failures và Exceptions sẽ cho thông tin về những lỗi và những requests bị failed trong quá trình chạy test.

Ngoài ra thì toàn bộ thông số trên có thể download dưới dạng CSV tại tab Download Data:

download.PNGHơn hết, Locust còn cung cấp một số endpoints nhất định để lấy tất cả những metrics trên về  hoặc chúng ta có thể vô hẳn trong code của Locust, import bộ stats và tự collect info từ đó nếu cần thiết.

Một vài thứ khác…

Multi-Locust script (Tạm dịch: đa bọ :v)

Chúng ta có thể define nhiều lớp Locust khác nhau trong cùng một locust file. Ví dụ: (multilocust.py):

multilocust.PNGVới vị dụ trên, chúng ta có hai lớp Locust khác nhau: Normal User đại diện cho một user bình thường với một tập TaskSet khác hẳn với Admin User. Và file trên có thể chạy theo một trong 2 cách sau:

locust -f multilocust.py # Chạy với tất cả lớp Locust được khai báo
locust -f multilocust.py AdminUser # Chỉ chạy với lớp Admin User

Số lượng users sẽ được chia dựa trên thuộc tính weight trong mỗi lớp, nếu không được đặt thì sẽ mặc định bằng 1. Như ở ví dụ trên, ta có Admin User với weight là bằng 2, và Normal User có weight chỉ bằng 1, nếu số lượng users được đề ra là 90, sẽ có 60 users thuộc lớp AdminUser và 30 users thuộc lớp NormalUser.

Min wait / Max wait

Ở giữa các tasks sẽ có một khoảng wait time nhất định, hai thuộc tính min_wait và max_wait được chỉ định sẽ làm mức cho wait time. Ví dụ min_wait là 1000 (1 giây) và max_wait là 3000 (3 giây) thì wait_time sẽ được random trong khoảng từ một tới ba giây này.

Khai báo @task

Có hai cách để khai báo một task (tác vụ) trong một TaskSet.

Cách thứ nhất là sử dụng @task decorator như những ví dụ trước.

Cách thứ hai là khai báo một danh sách với tên gọi là tasks và thêm những hàm task vào trong danh sách này:

tasks.PNG

@task cũng có thuộc tính weight giống với lớp Locust, bằng cách thêm như biến vào decorator:

taskweight

Ở ví dụ trên, chúng ta có task “get_index” với gái trị weight bằng 3 và post_index với giá trị weight bằng 1, Locust sẽ quản lý task cho task get_index sẽ luôn thực hiện gần gấp 3 lần số lần mà task post_index được thực hiện.

Đồng thời mỗi task sẽ được thực hiện theo thứ tự ngẫu nhiên. Để sắp xếp thứ tự từ trên xuống dưới, bạn có thể bỏ nhiều requests vô chung một task và nó sẽ thực hiện theo code như bình thường. Một cách khác có thể áp dụng đó là sử dụng lớp TaskSequence (hiện chỉ có trong phiên bản 0.9.0).

Sử dụng TaskSequence

Lớp TaskSequence tương tự như lớp TaskSet nhưng yêu cầu truyền thêm biến thứ tự cho một tác vụ thông qua sử dụng decoractor @seq_task đi kèm:

seqtasks.PNG

Thứ tự thực hiện ở trên: login_first -> then_read_thread -> then _logout

Setup, teardown, on_start, on_stop

Locust cũng hỗ trợ một số hàm như setup / teardown/on_start/on_stop (~ giống với BeforeAll / AfterAll / BeforeEach / AfterEach trong mấy cái test framework khác):

lifecycle.PNG

  • Setup trong lớp Locust: Chỉ chạy một lần trước khi bắt đầu test.
  • Teardown trong lớp Locust: Chỉ chạy một lần sau khi kết thúc test.
  • Setup trong lớp TaskSet: Chỉ chạy một lần trước khi bắt đầu test và khác với Setup trong lớp Locust, nếu có nó sẽ chạy sau Setup của lớp Locust.
  • Teardown trong lớp TaskSet: Chỉ chạy một lần sau khi kết thúc test và khác với Teardon trong lớp Locust, nếu có nó sẽ chạy trước Teardown của lớp Locust.
  • on_start trong TaskSet: Thực hiện cho mỗi instance Locust khi chúng được sinh ra.
  • on_stop in TaskSet: Thực hiện cho mỗi instance Locust khi chúng chết.

Xử lý HTTP requests

Như mình đã đề cập, lớp HttpLocust sẽ tạo một thuộc tính client đại hiện cho một instance từ class HttpSession của thư viện Request bên Python. Có thể tham khảo thêm cách sử dụng thư viện này thì tài liệu của thư viện.

Một số API khác

Locust còn một số API khác hỗ trợ cho việc viết script, do scope của bài viết không đủ , mọi người có thể xem thêm tại  bộ docs của Locust.

Sử dụng Locust với distribution mode

Để sử dụng Locust với distribution mode, chúng ta chỉ việc đơn giản sử dụng cờ –master và –slave.

Đầu tiên, chạy Master locust trước với vai trò trung gian điều khiển những máy Slaves, để chạy Master, ta cần một locust file dummy, file này không có ý nghĩa gì nhiều nhưng có thể dùng để customize lại Web UI và thêm một số end points cần thiết.

Tiếp theo ta sẽ chạy Slave locust, lúc này thì sẽ cần đi kèm với locustfile chứ đoạn script chạy test: (bạn nhớ thay IP của máy Master vào cờ –master-host trong lệnh phía dưới nha)

locust -f locustfile_slave.py --slave --master-host=<IP-of-the-host>

Bạn có thể thử mở tay nhiều terminal / command prompt và add từng Slave vào. Sau đó vào web UI và chạy test như bình thường.

Như bạn thấy thì việc setup chạy Locust với distribution mode khá là đơn giản và nhanh chóng. Do đó chúng ta có thể tận dụng một số hệ thống cluster như Kubernetes hay Docker Swarm để setup hệ thống này scale cực nhanh số lượng Slaves lớn nếu cần thiết. Mình sẽ có một bài viết hướng dẫn chi tiết hơn về cách thiết lập hệ thống như vậy sau.

Dưới đây là một đoạn demo ngắn về việc scale up Locust với Kubernetes và quản lý các Slave instances thông qua WeaveScope

locust

Tóm lại thì…

Về tổng thể thì Locust được tạo ra nhằm giải quyết một số vấn đề mà những tools hiện tại đang mắc phải như việc maintain script khó khăn, khả năng scaling khó khăn. Đồng thời Locust cũng khá là “nhẹ kí” và dễ dàng customize, extend thêm được nhiều tính năng mới nếu cần thiết.

Tạm vậy. Mình sẽ viết nhiều bài hướng dẫn cụ thể hơn trong tương lai và explore nhiều tính năng khác của Locust.

======================================================

Preface

In this article, I’d like to introduce Locust – a load testing tool that is written in Python which has many interesting features that I think might be helpful for the Performance Testers whose are considering a new method / solution for the Load testing framework.

In this post, I try to cover the basics of Locust and will update more detail tutorials in other related future articles.

Note: The source code of the demos in this blog can be found in this repository.

Introduction

The original idea for Locust was from Carl Byström who made the first proof of concept in June 2010.  Jonatan Heyman picked up Locust in January 2011, implemented the current concept of Locust classes and made it work distributed across multiple machines. Then, ESN Social Software has adopted Locust as an in-house Open Source project.

The main idea is about making a load testing tool which helps to write test scenarios in plain code and can run distributed load tests easily. Here we have Locust.

Getting started with Locust

Installation

Before installing Locust, ensure that you have Python 3.6+ running on your computer.

Installing with pip (Recommended for Stable version)

The simplest way to install Locust is using pip:

pip install locustio

After the installation, you can check the version of Locust by using the command:

locust --version
[2018-08-26 17:03:14,986] ./INFO/stdout: Locust 0.8.1

Installing the latest version from GitHub (Latest dev version)

The stable version at the time this post was written was 0.8.1. Apparently the version missed a few newest features. If you want the latest version from the developers, you could download from the GitHub Repository and install from there:

git clone https://github.com/locustio/locust.git
cd locust
python setup.py install

Installing with Docker

For now, there is no official Docker image for Locust, but you can pull it from the following source or build the image yourself:

docker pull quay.io/honestbee/locust

Writing your first Locustfile

OK. We have finished installing Locust library on our machines. Let’s jump right into it and start writing our test script.

But wait, we need to prepare some simple API endpoints first. I will use Flask for the quick setup:

pip install flask

Create a main.py file (or whatever.py file):

# main.py
from flask import Flask, request, jsonify, app

import time
import random

app = Flask(__name__)

@app.route('/api', methods=['GET', 'POST'])
def index():
    if request.method =='GET':
        return jsonify(method=request.method)
    return jsonify(method=request.method,payload=request.json)

if __name__ == '__main__':
    app.run(host='0.0.0.0')

The above code contains an “/api” route which will return the requests’ methods under JSON format and it accepts GET or POST requests only. Also if it was a POST request with the JSON body, we will also return the payload, too.

Start running the API server, it will be exposed on port 5000:

python main.py
* Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)

Okay, now we have our “system under test”. We can start some testing activities.

Locust requires at least one locustfile – just a normal Python file (.py) – which contains one or more Locust classes to run the test.

A simple locustfile would look like this:

# locustfile.py
from locust import Locust, TaskSet, task

class UserTaskSet(TaskSet):              #3
    @task                                #4
    def my_task(self):
        print("executing my_task")

class User(Locust):                      #1
    task_set = UserTaskSet               #2 
    min_wait = 5000
    max_wait = 15000

At #1, we have the User class inherited from the Locust class. A locust class represents a virtual user that will perform the tasks written in the task sets managed by the Locust.

In the above example, we have defined User and we set the task_set attribute to the UserTaskSet class which inherited from TaskSet class. (#2, #3). And to define a task to be performed in the TaskSet, we add the @task decorator before the method (#4)

You can start running the script by using the locust command, Locust will find the file with the name “locustfile”. If you named it something else, you can add the -f flag with the name you set:

locust -f whatever.py

You can access to the Web UI at http://localhost:8089/ .

webui.PNG

You can set a number of users and the hatch rate (how many users will be spawned each second). Then start swarming.

For now, our script only makes the users printing out “executing my_task” string. Let’s define some real tasks for our virtual users.

To simulate some HTTP requests, we need our Locust to have some specific options and methods . The HttpLocust is written for this purpose. It is an implementation of the Locust class that will create an HTTP client attribute on instantiation which supports for managing HTTP requests / responses.

Let’s modify our script a little:

# locustfile.py
from locust import HttpLocust, TaskSet, task 

class UserTaskSet(TaskSet):
    @task
    def get_index_task(self): 
        self.client.get("/api")    #3 

class User(HttpLocust):            #1 
    task_set = UserTaskSet 
    min_wait = 5000 
    max_wait = 15000
    host = "http://localhost:5000" #2

#1 The User class before now inherited from HttpLocust class.

#2 Define the target host (which is our API server from before) with the host attribute in HttpLocust class.

#3  The “self” in the task methods is the instance of the HttpLocust class, which we can call the client attribute from it and use the method ‘get’ to the “/api” endpoint.

Now, add a new task which send a POST request to the server:

# locustfile.py
from locust import HttpLocust, TaskSet, task 

class UserTaskSet(TaskSet):
    @task
    def get_index_task(self): 
        self.client.get("/api", name="GET /api")

    @task
    def post_index_task(self):        # New task here
        payload = {'username': 'locmai'}
        self.client.post("/api", data=payload, name="POST /api")

class User(HttpLocust):
    task_set = UserTaskSet 
    min_wait = 5000 
    max_wait = 15000
    host = "http://localhost:5000"

As adding the new task, we can set a name for the each request as the parameters.

Start running our script:

locust -f locustfile.py

Open the browser and navigate to the http://localhost:8089/ , enter the number of virtual users and the hatch rate, then click Start Swarming

starttesting.PNG

That’s it! Now we can go deeper into the APIs that Locust provide and we can write more flexible script.

Web UI

Locust provides a Web UI that shows relevant test details and control the test runs. You can also customize it and add a few extra features yourself if you wanted to (I might have another post on how to do it and provide some use cases later on).

On the top navigation bar, you can see the details about the Target Host, users’ status, number of users hatched and update a new desired number, RPS, Failures rate. Stop and reset statistic details button.

starttesting.PNG

In the main section, we have Statistics tab which shows some basic information related to our test run like type of the request, name, number of request executed successfully and unsuccessfully, the average, min, max response times, etc.

In the Charts tab, we have just a few but enough .live charts:

charts.PNG

The failures and the Exceptions tabs show what requests failed and the errors thrown during the test runs.

And we can also download all the test details with CSV format in the Download Data tab

download.PNG Locust also exposes some endpoints for getting the metrics. I will mention in another blog post for more details and more specific.

Other Locust’s stuffs

Multi-Locust script

We can define different Locust classes in the same locust file. For example (multilocust.py):

multilocust.PNG As in the above example, we have two different Locust classes: Normal User represents the normal user that has a different TaskSet from the Admin User class. The file could run by the following commands:

locust -f multilocust.py # Run test with all Locust classes
locust -f multilocust.py AdminUser # Run test with only AdminUser

The users distribution will be based on the weight of the HttpLocust classes, if not set, the default weight will be 1. As in the example, the AdminUser has the weight of 2, NormalUser only has 1, if we set the number of users to 90, there will be 60 Admin users and 30 Normal users.

Min wait / Max wait

The wait time before executing tasks will be randomized in the range of min_wait and max_wait attributes. These attributes can be set in the HttpLocust class or the TaskSet class.

Defining @task methods

There are two ways to define a task in a TaskSet class.

The first way is to use the @task decorator as shown in the previous examples.

The second way is to declare a list called tasks in the TaskSet class and adding the methods into the list:

tasks.PNG

We can also set the task’s weight (just like the weight of Locust class – but for tasks) by adding the parameters:

taskweight

In the above example, we have task get_index with the weight is 3 and the post_index’s weight is 1. So that the task get_index will likely be executed more than 3 times the number of times the task post_index be executed.

The tasks will be performed in a random order. To make a sequence order for the requests, you can add the requests into one tasks with the order you want. Or you can use the TaskSequence class which will be introduced in version 0.9.0 ( You can try it out by installing the latest version)

Using TaskSequence with @seq_task

The TaskSequence is similar to the TaskSet class but it requires for the order of the tasks by adding the @seq_task(order_param) decorator before the methods:

seqtasks.PNG

In the example, the tasks will be executed by the order: login_first -> then_read_thread -> then _logout

Setup, teardown, on_start, on_stop

We can manage the test cycle with the default methods:

lifecycle.PNG

  • Setup method in Locust class: Will be executed once before the test started.
  • Teardown method in Locust class: Will be excuted once after test stopped.
  • Setup method in TaskSet class: Will be executed once (and differ from the one in Locust class) before the test started.
  • Teardown method in TaskSet class: Will be excuted once (and differ from the one in Locust class) after the test stopped.
  • on_start in TaskSet: Will be executed for each locust instance hatched.
  • on_stop in TaskSet: Will be executed for each locust instance after they died / stopped.

Handling HTTP requests

As mentioned, HttpLocust class will create a client attribute which actually is an instance of the HttpSession from the default request library of Python. You can read more about the API in the Official doc here.

Other APIs

For more detail information on how to implement new event hooks, responses handling, please refer to the official Locust docs.  I will have a detail blog post on how to customize the APIs soon.

Running Locust distributed

We have go through a simple list of the APIs and how to implement basic Locust scripts. Now we are going to setup the distribution for our load tests.

You can enable distribution mode by using the –master and –slave flags.

First, start the Master locust which will be responsible for controlling the slave instances. You  will need a dummy locustfile for starting the master, this file could be use for customizing the Web UI if needed.

locust -f dummy.py --master

Now start the Locust slave and connect it to the master instance, you will have to define the locustfile for running the test here:

locust -f locustfile_slave.py --slave --master-host=<IP-of-the-host>

Manually adding the Locust slaves. You can access the Web UI and see how many slaves have been added to the cluster. And simply start running test on the Web UI as usual.

As you can see, the setup for running Locust in distributed mode is pretty simple. We can even leverage some Cluster systems like Kubernetes or Docker Swarm for quickly scale up the slaves, I will have a details blog post on how to setup a distributed system on Kubernetes cluster with all the configurations.

For example, you can scale up the Locust cluster with Helm and Kubernetes and easily mange them all:

locust

In summary

Overall, Locust was created to solve some specific issues of current existing performance tools, and it did a great job. Using this framework and some Python experience you can write performance scripts pretty fast, store them within your Python project, spend minimum time on maintenance without additional GUI applications and simulate thousands of test users even on a very slow machine. The framework is also small and very extendable which is the great feature for us to explore more about this tool.

And that’s it for now. See you soon in the future Locust articles.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s