杰瑞科技汇

Python负载测试怎么做?工具选择与关键步骤

Of course! "Python load tests" is a broad topic, so let's break it down into a comprehensive guide covering the concepts, tools, and a practical, step-by-step example.

Python负载测试怎么做?工具选择与关键步骤-图1
(图片来源网络,侵删)

What is Load Testing?

Load testing is a type of non-functional testing that simulates a real-world load on a software application or website. The goal is to understand how the system behaves under a specific expected number of concurrent users.

Key Objectives:

  • Identify Performance Bottlenecks: Where does the application slow down? (e.g., database queries, slow API calls, inefficient code).
  • Determine System Capacity: What is the maximum number of users the system can handle before performance degrades significantly?
  • Monitor Resource Utilization: How much CPU, memory, disk I/O, and network bandwidth are being used?
  • Validate SLAs (Service Level Agreements): Ensure the system meets its performance promises (e.g., "95% of requests must be served in under 200ms").

Key Concepts in Load Testing

Before we start, it's crucial to understand a few terms:

  • VUsers (Virtual Users): These are simulated users generated by the load testing tool. They are not real people but scripts that perform actions on your application.
  • Ramp-up Period: The time it takes for the load testing tool to start all the VUsers. For example, ramping up 100 users over 60 seconds means a new user is started every 0.6 seconds. This simulates a more realistic, gradual increase in traffic.
  • Think Time: The time a simulated user "pauses" between actions. For example, after logging in, a user might spend 5-10 seconds browsing before clicking a link. This makes your load test more realistic.
  • Load Profile: The pattern of VUsers over time. It can be:
    • Constant Load: A fixed number of VUsers for a duration.
    • Ramp-up Load: Gradually increasing the number of VUsers.
    • Spike Load: A sudden, large increase in VUsers to test how the system handles traffic bursts.
  • Metrics: The data you collect during the test. The most important ones are:
    • Response Time: How long it takes for the server to respond to a request.
    • Throughput: The number of requests the server can handle per second (RPS).
    • Error Rate: The percentage of requests that fail.
    • Resource Utilization: CPU, Memory, etc., on your servers.

Popular Python Load Testing Tools

Here are the most common tools used for load testing with Python, ranging from simple to highly advanced.

Python负载测试怎么做?工具选择与关键步骤-图2
(图片来源网络,侵删)
Tool Best For Key Features Complexity
locust Most use cases. API, website, UI testing. Python-based, code-based, distributed, web UI, great for beginners and experts. Low
k6 Modern, API-first testing. JavaScript-based, real-time metrics, cloud reporting, strong community. Medium
pytest + locust Developers who love pytest. Leverages the pytest ecosystem for complex test logic and fixtures. Medium
Artillery Complex, scenario-based tests. YAML/JS configuration, supports plugins, good for microservices. Medium
Gatling High-performance, enterprise-grade. Scala-based, generates HTML reports, extremely fast simulation engine. High

For this guide, we'll focus on locust because it's incredibly popular, easy to start with, and powerful enough for most needs.


Step-by-Step Example: Load Testing a Web API with locust

Let's build a simple load test for a public API. We'll use the JSONPlaceholder API, a free fake REST API for testing.

Goal: Simulate 100 users hitting the /posts/1 endpoint over a 2-minute period.

Step 1: Install Locust

First, you need to install locust. It's recommended to do this in a virtual environment.

Python负载测试怎么做?工具选择与关键步骤-图3
(图片来源网络,侵删)
# Create and activate a virtual environment (optional but recommended)
python -m venv venv
source venv/bin/activate  # On Windows: venv\Scripts\activate
# Install locust
pip install locust

Step 2: Create the Test Script (locustfile.py)

In your project directory, create a file named locustfile.py. This is the heart of your test. locust automatically looks for this file.

# locustfile.py
from locust import HttpUser, task, between
class WebsiteUser(HttpUser):
    """
    This user class represents a virtual user that will perform tasks.
    It's an HttpUser, so it can make HTTP requests.
    """
    # Wait time between executing tasks (in seconds)
    # This simulates a user's "think time"
    wait_time = between(1, 5)
    @task
    def get_post(self):
        """
        This is a task that a virtual user will perform.
        The @task decorator tells locust this is a task to be executed.
        """
        # The client attribute is an instance of requests.Session
        self.client.get("/posts/1")

Explanation:

  • HttpUser: A class that represents a user who will make HTTP requests.
  • wait_time = between(1, 5): Each virtual user will wait a random amount of time between 1 and 5 seconds after completing a task.
  • @task: This decorator marks a method as a load testing task. By default, tasks are picked at random. If you have multiple tasks, their relative weight can be controlled by the weight parameter (e.g., @task(3)).

Step 3: Run the Load Test

Open your terminal in the same directory as locustfile.py and run:

locust

You will see output like this:

[2025-10-27 10:30:00,123] INFO/locust.main: Starting web UI at http://localhost:8089/
[2025-10-27 10:30:00,123] INFO/locust.main: Starting Locust 2.17.0

Step 4: Configure and Start the Test from the Web UI

  1. Open your web browser and navigate to http://localhost:8089.
  2. You'll see the Locust dashboard.
    • Number of users to simulate (Number of Users): Set this to 100.
    • Ramp up time (in seconds) (Spawn Rate): Set this to 50. This means Locust will start 100 users over 50 seconds (2 users per second). This is much more realistic than starting all 100 at once.
  3. Click the "Start swarming" button.

Step 5: Analyze the Results

As the test runs, you'll see real-time statistics in the web UI.

  • Statistics Table: Shows a summary of all requests. You'll see your GET /posts/1 request with its Response Time, RPS (Requests Per Second), and Failures.
  • Charts: Interactive charts show you how RPS and Response Time change over time.
  • Console Output: The terminal will also print logs.

After 2 minutes, you can stop the test by clicking the "Stop" button in the web UI.


Advanced locust Features

The simple example is great, but real-world tests are more complex.

A. Adding Headers and Authentication

Most APIs require headers (like Content-Type) or authentication (like an API key or a JWT token).

# locustfile.py (Advanced)
from locust import HttpUser, task, between
import os # To get secrets from environment variables
class AuthenticatedUser(HttpUser):
    wait_time = between(1, 3)
    def on_start(self):
        """
        This method is called when a user starts.
        Perfect for logging in or getting an auth token.
        """
        # Example: Getting a JWT token
        response = self.client.post("/login", json={"username": "test", "password": "test"})
        if response.status_code == 200:
            # Store the token in the session for future requests
            self.token = response.json()["token"]
            self.headers = {"Authorization": f"Bearer {self.token}"}
        else:
            print("Failed to get token!")
    @task
    def create_and_get_post(self):
        # Add headers to the request
        response = self.client.get("/posts/1", headers=self.headers)
        # You can add assertions to check response status
        assert response.status_code == 200

B. Writing More Realistic Scenarios (Task Sets)

For complex user flows (e.g., browse products -> add to cart -> checkout), use TaskSet.

# locustfile.py (TaskSet Example)
from locust import HttpUser, task, between
from locust.task import TaskSet
class UserBehavior(TaskSet):
    @task(3) # This task will be 3 times more likely to be picked than the next one
    def browse_posts(self):
        self.client.get("/posts")
    @task(1)
    def view_specific_post(self):
        self.client.get("/posts/1")
class WebsiteUser(HttpUser):
    tasks = [UserBehavior] # Assign the TaskSet to the user
    wait_time = between(1, 5)

C. Running Distributed Load Tests

For testing larger systems, you need more than one machine.

  1. Master Node: The machine where you run locust -f locustfile.py --master.
  2. Worker Nodes: Other machines where you run locust -f locustfile.py --worker --master-host=<MASTER_IP_ADDRESS>.

All workers will report back to the master, which aggregates the data in its web UI.


Best Practices for Python Load Testing

  1. Test in a Staging Environment: Never run heavy load tests against your production database. Use a staging environment that mirrors production as closely as possible.
  2. Start Small, Scale Gradually: Begin with a small number of users and gradually increase the load. This helps you pinpoint exactly when and why performance degrades.
  3. Monitor Everything: Don't just look at application metrics. Monitor the underlying infrastructure (CPU, memory, network) on your servers using tools like Prometheus/Grafana, Datadog, or New Relic.
  4. Use Realistic Data: Use test data that resembles your production data. If your app handles large files, test with large files. If users have different roles, simulate them.
  5. Separate Test Logic from Business Logic: Keep your locustfile focused on simulation. Use libraries or helper functions to manage complex data generation or API interactions.
  6. Automate Your Tests: Integrate your load tests into your CI/CD pipeline (e.g., Jenkins, GitLab CI) to run them on every merge request. This catches performance regressions early.
分享:
扫描分享到社交APP
上一篇
下一篇