Sấu Gấu Blog


Python Locust Testing: Load Testing Made Simple

A comprehensive guide to performance testing with Locust - from basics to advanced techniques
Locust is a powerful and easy-to-use load testing tool written in Python. In this article, I'll share my experience using Locust to test website and API performance, from basic concepts to advanced techniques.

What is Locust?

Locust is an open-source framework for load testing written in Python. It allows you to write test scenarios using Python code, making it easier to create complex test cases compared to traditional tools like Apache JMeter.

Advantages of Locust:

Installation and Setup

# Install Locust
pip install locust

# Or use requirements.txt
echo "locust>=2.15.0" >> requirements.txt
pip install -r requirements.txt

Basic Structure of a Locust Test

A basic Locust test file has the following structure:
from locust import HttpUser, task, between

class WebsiteUser(HttpUser):
    wait_time = between(1, 3)  # Wait time between requests
    
    def on_start(self):
        """Runs when user starts testing"""
        pass
    
    @task
    def index_page(self):
        """Test homepage"""
        self.client.get("/")
    
    @task(2)  # Weight 2 - runs twice as often as other tasks
    def view_item(self):
        """Test viewing product"""
        self.client.get("/item/1")

Real-world Example: Testing API with Authentication

Based on my real-world experience, here's an example of testing an API with authentication:
import random
from locust import HttpUser, task, between

USER_CREDENTIALS = [
    ("user1", "password1"),
    ("user2", "password2")
]

class APIUser(HttpUser):
    wait_time = between(15, 30)  # Simulate user think time
    
    def on_start(self):
        """Login when starting test"""
        self.access_token = None
        self.user_id = None
        self.login()
        self.get_user_info()
    
    def login(self):
        """Login and store access token"""
        username, password = random.choice(USER_CREDENTIALS)
        response = self.client.post("/api/v1/auth/login", json={
            "username": username,
            "password": password
        })
        
        if response.status_code == 200:
            data = response.json()
            self.access_token = data.get("data", {}).get("accessToken")
    
    def get_auth_headers(self):
        """Helper to create Authorization header"""
        return {"Authorization": f"Bearer {self.access_token}"} if self.access_token else {}
    
    @task(1)
    def get_user_info(self):
        """Get user information"""
        response = self.client.get("/api/v1/auth/me", 
                                 headers=self.get_auth_headers())
        if response.ok:
            data = response.json().get("data", {})
            self.user_id = data.get("id")
    
    @task(2)
    def get_dashboard_stats(self):
        """Get dashboard statistics"""
        if self.user_id:
            params = {"userId": self.user_id}
            response = self.client.get("/api/v1/dashboard/stats", 
                                     params=params, 
                                     headers=self.get_auth_headers())

Important Concepts

1. User Classes

User classes define the behavior of virtual users. Each user will run tasks according to the defined order and timing.

2. Tasks

Tasks are actions that users perform. Use the @task decorator to mark a method as a task.

3. Wait Time

wait_time defines the waiting time between tasks:

4. Task Weighting

Use @task(weight) to define the frequency of each task. Tasks with higher weights will run more often.

Running Locust Tests

Command Line

# Run test with locustfile.py
locust -f locustfile.py

# Run with specific host
locust -f locustfile.py --host=http://localhost:8000

# Run in headless mode (no web UI)
locust -f locustfile.py --host=http://localhost:8000 --headless --users 10 --spawn-rate 2 --run-time 60s

Web UI

After running the command above, open your browser and visit http://localhost:8089 to view Locust's web UI.

Monitoring and Metrics

Locust provides important real-time metrics:

Distributed Testing

To run tests on multiple machines: Master node:
locust -f locustfile.py --master
Worker nodes:
locust -f locustfile.py --worker --master-host=MASTER_IP

Best Practices

Advanced Example: Testing with Custom Data

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

class AdvancedAPIUser(HttpUser):
    wait_time = between(1, 5)
    
    def on_start(self):
        """Load test data from CSV file"""
        self.test_data = self.load_test_data()
        self.current_data = random.choice(self.test_data)
    
    def load_test_data(self):
        """Load data from CSV file"""
        data = []
        with open('test_data.csv', 'r') as file:
            reader = csv.DictReader(file)
            for row in reader:
                data.append(row)
        return data
    
    @task
    def create_resource(self):
        """Create resource with random data"""
        payload = {
            "name": f"Test_{random.randint(1000, 9999)}",
            "description": "Generated by Locust test",
            "data": self.current_data
        }
        
        response = self.client.post("/api/resources", 
                                  json=payload,
                                  headers={"Content-Type": "application/json"})
        
        if response.status_code == 201:
            # Save ID for use in subsequent requests
            self.resource_id = response.json().get("id")
    
    @task
    def update_resource(self):
        """Update created resource"""
        if hasattr(self, 'resource_id'):
            payload = {"status": "updated"}
            self.client.put(f"/api/resources/{self.resource_id}", 
                           json=payload)

Conclusion

Locust is a powerful tool for load testing, especially suitable for Python developers. With simple syntax, intuitive web UI, and scalability, Locust makes performance testing easier and more effective. When to use Locust: When not to use Locust: With Locust, you can easily create complex test scenarios and monitor system performance in real-time. This is an essential tool in the toolkit of any DevOps engineer or developer concerned with performance testing.
Ngày đăng: Aug. 24, 2025
8 total views

Comment

Hiện tại chưa có comment nào...