第三方软件测评机构:【Locust的性能测试和负载测试】

Locust是一个用Python编写的开源负载测试工具,它允许使用Python代码定义用户行为,能够模拟数百万用户并发来测试您的系统。

Locust的优势:使用纯 Python 编写测试场景、分布式支持轻松扩展到多台机器、实时Web UI更直观监控测试进度和结果、高并发能力是基于gevent的协程实现

1.安装与配置

基础安装

bash 复制代码
# 使用 pip 安装
pip install locust

# 验证安装
locust --version

选择依赖项

bash 复制代码
# 安装带额外功能的版本
pip install locust[extra]

# 或单独安装所需组件
pip install pyzmq  # 分布式模式支持
pip install geventhttpclient  # 更快的 HTTP 客户端

2. 脚本编写

创建基础测试脚本-locustfile.py

python 复制代码
from locust import HttpUser, TaskSet, task, between
import random

class UserBehavior(TaskSet):
    
    @task(3)  # 权重为3,执行频率更高
    def view_products(self):
        # 查看产品列表
        self.client.get("/api/products")
    
    @task(2)
    def view_product_detail(self):
        # 查看产品详情,使用随机ID
        product_id = random.randint(1, 100)
        self.client.get(f"/api/products/{product_id}")
    
    @task(1)
    def create_order(self):
        # 创建订单
        headers = {'Content-Type': 'application/json'}
        data = {
            "product_id": random.randint(1, 100),
            "quantity": random.randint(1, 5)
        }
        self.client.post("/api/orders", json=data, headers=headers)

class WebsiteUser(HttpUser):
    tasks = [UserBehavior]
    wait_time = between(1, 5)  # 用户等待时间1-5秒
    
    def on_start(self):
        # 用户启动时执行(如登录)
        self.client.post("/api/login", json={
            "username": "test_user",
            "password": "test_pass"
        })

3. 功能配置

自定义客户端配置

python 复制代码
from locust import HttpUser, task
import json

class ApiUser(HttpUser):
    host = "https://api.zmtests.com"
    
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.client.verify = False  # 禁用SSL验证
        self.client.timeout = 30    # 设置超时时间
    
    @task
    def complex_request(self):
        # 自定义请求头
        headers = {
            "Authorization": "Bearer token123",
            "User-Agent": "LocustLoadTest/1.0"
        }
        
        # 带参数的GET请求
        params = {"page": 1, "limit": 20}
        response = self.client.get("/api/data", params=params, headers=headers)
        
        # 处理响应
        if response.status_code == 200:
            data = response.json()
            print(f"Received {len(data)} items")

事件钩子编写

python 复制代码
from locust import events
from locust.runners import MasterRunner, WorkerRunner
import time

@events.test_start.add_listener
def on_test_start(environment, **kwargs):
    print("测试开始执行")
    if isinstance(environment.runner, MasterRunner):
        print("这是Master节点")
    elif isinstance(environment.runner, WorkerRunner):
        print("这是Worker节点")

@events.request.add_listener
def on_request(request_type, name, response_time, response_length, 
               response, context, exception, **kwargs):
    if exception:
        print(f"请求失败: {name}, 错误: {exception}")
    else:
        print(f"请求成功: {name}, 响应时间: {response_time}ms")

@events.test_stop.add_listener
def on_test_stop(environment, **kwargs):
    print("测试结束")

4. 运行

启动方式

Web UI 模式

bash 复制代码
# 基础启动
locust -f locustfile.py

# 指定主机和端口
locust -f locustfile.py --host=https://api.zmtests.com --web-port=8080

# 无Web界面模式(用于CI/CD)
locust -f locustfile.py --headless -u 100 -r 10 -t 10m

命令行参数

bash 复制代码
locust -f locustfile.py \
    --host=https://api.zmtests.com \
    --users=1000 \          # 最大用户数
    --spawn-rate=10 \       # 每秒启动用户数
    --run-time=30m \        # 运行时间
    --web-host=0.0.0.0 \    # Web界面绑定地址
    --web-port=8080 \       # Web界面端口
    --headless \            # 无头模式
    --csv=results \         # 导出CSV结果
    --html=report.html      # 生成HTML报告

分布式运行

bash 复制代码
# 启动Master节点
locust -f locustfile.py --master --expect-workers=4

# 启动Worker节点(在其他机器上)
locust -f locustfile.py --worker --master-host=192.168.1.100

5. 性能优化

优化测试脚本

python 复制代码
from locust import HttpUser, task, events
import gevent
from gevent.pool import Group

class OptimizedUser(HttpUser):
    
    @task
    def parallel_requests(self):
        # 并行执行多个请求
        urls = [
            "/api/products",
            "/api/categories", 
            "/api/users/me"
        ]
        
        group = Group()
        for url in urls:
            group.spawn(lambda u=url: self.client.get(u))
        group.join()
    
    @task
    def batch_operations(self):
        # 批量操作减少请求次数
        orders = [
            {"product_id": i, "quantity": 1} 
            for i in range(1, 6)
        ]
        self.client.post("/api/orders/batch", json=orders)

自定义客户端

python 复制代码
from locust import HttpUser
from locust.clients import HttpSession
import urllib3

class CustomHttpUser(HttpUser):
    
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # 禁用不安全请求警告
        urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
        
    @task
    def custom_request(self):
        # 使用连接池和会话复用
        with self.client.get("/api/data", catch_response=True) as response:
            if response.elapsed.total_seconds() > 2:
                response.failure("响应时间过长")
            elif response.status_code != 200:
                response.failure(f"HTTP错误: {response.status_code}")
            else:
                response.success()

6. 数据驱动测试

python 复制代码
import csv
import json
from locust import HttpUser, task

class DataDrivenUser(HttpUser):
    
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.test_data = self.load_test_data()
    
    def load_test_data(self):
        # 从CSV文件加载测试数据
        data = []
        with open('test_data.csv', 'r') as f:
            reader = csv.DictReader(f)
            for row in reader:
                data.append(row)
        return data
    
    @task
    def create_user(self):
        if self.test_data:
            user_data = random.choice(self.test_data)
            self.client.post("/api/users", json=user_data)

7. 验证

python 复制代码
from locust import HttpUser, task
import jsonschema
from jsonschema import validate

class ValidatingUser(HttpUser):
    
    user_schema = {
        "type": "object",
        "properties": {
            "id": {"type": "integer"},
            "name": {"type": "string"},
            "email": {"type": "string", "format": "email"}
        },
        "required": ["id", "name", "email"]
    }
    
    @task
    def validate_response(self):
        with self.client.get("/api/user/1", catch_response=True) as response:
            try:
                data = response.json()
                validate(instance=data, schema=self.user_schema)
                
                # 自定义业务逻辑验证
                if data["name"] and len(data["name"]) > 0:
                    response.success()
                else:
                    response.failure("用户名无效")
                    
            except jsonschema.ValidationError as e:
                response.failure(f"响应格式错误: {e}")
            except ValueError:
                response.failure("响应不是有效的JSON")

8. 集成与自动化

bash 复制代码
FROM python:3.9
RUN pip install locust
COPY locustfile.py /mnt/locustfile.py
WORKDIR /mnt
EXPOSE 8089
CMD ["locust", "-f", "locustfile.py", "--host", "http://target-service"]

CI/CD 集成

bash 复制代码
#yaml
name: Load Test
on: [push]
jobs:
  load-test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Setup Python
        uses: actions/setup-python@v2
        with:
          python-version: '3.9'
      - name: Install dependencies
        run: pip install locust
      - name: Run load test
        run: |
          locust -f locustfile.py \
            --headless \
            --users 100 \
            --spawn-rate 10 \
            --run-time 5m \
            --host ${{ secrets.TARGET_HOST }} \
            --html report.html \
            --only-summary
相关推荐
程序员杰哥9 小时前
Pytest与Unittest测试框架对比
自动化测试·软件测试·python·测试工具·测试用例·excel·pytest
软件测试小仙女9 小时前
Pytest参数化实战:高效测试API接口
软件测试·测试开发·测试工具·pytest·接口测试·api·参数化
00后程序员张13 小时前
Fiddler抓包工具使用教程,代理设置与调试方法实战解析(含配置技巧)
前端·测试工具·ios·小程序·fiddler·uni-app·webview
Cd ...1 天前
记录两种好用常用的xpath定位方式
selenium·测试工具·自动化
一次旅行1 天前
DeepSeek生成测试用例方法
测试用例·测试总结
测试老哥2 天前
如何编写好测试用例?
自动化测试·软件测试·python·功能测试·测试工具·职场和发展·测试用例
AALoveTouch2 天前
大麦网抢票:基于Wireshark协议分析
网络·测试工具·wireshark
Run Freely9372 天前
Postman 请求前置脚本
测试工具·postman
我的xiaodoujiao2 天前
从 0 到 1 搭建 Python 语言 Web UI自动化测试学习系列 15--二次开发--封装公共方法 3
python·学习·测试工具