在日常的接口测试中,性能测试是验证系统稳定性的关键环节。相比于LoadRunner等重型商业工具,Locust凭借“Python编写、高并发、轻量易用”的特点,成为中小团队和个人开发者的首选。本文将以登录接口性能测试为例,从零讲解Locust的核心概念和实战用法,即使是性能测试新手也能快速上手。
一、Locust是什么?为什么选它?
Locust是一款基于Python的开源性能测试工具,核心优势如下:
纯Python编写:无需学习复杂的专有脚本,用熟悉的Python语法即可编写测试逻辑,灵活度拉满;
高并发特性:基于协程模型(gevent),单台普通服务器可模拟数万并发用户,资源占用远低于传统线程/进程模型工具;
Web可视化控制台:一键启动,直观查看响应时间、TPS、错误率等核心指标;
无侵入性:无需在被测系统中部署任何代理,仅通过HTTP请求压测,对业务无影响;
完全免费:开源无授权费用,适合小团队/个人使用。
本文将以“小程序登录接口(/wx/auth/login)”为测试目标,完整演示Locust从环境搭建到结果分析的全流程。
二、环境准备
1. 基础环境
确保本地已安装Python(3.7+版本,推荐3.9/3.10),验证方式:
python --version # 或 python3 --version2. 安装Locust
使用pip快速安装Locust:
pip install locust验证安装成功:
locust -V # 输出Locust版本号即安装成功(如locust 2.42.6)三、Locust核心概念(新手必懂)
在编写脚本前,先理解Locust的3个核心概念,结合登录场景通俗解释:
四、实战:编写登录接口压测脚本
1. 测试目标说明
本次测试的登录接口信息:
接口地址:
/wx/auth/login请求方式:POST
请求体:
{"username": "user124", "password": "user123"}响应成功标识:
errno=0、errmsg="成功"测试数据:从
test_users.json中读取100个测试用户账号
2. 完整脚本编写
新建login_perf_test.py文件,代码如下(含详细注释):
import json
import random
from locust import HttpUser, task, between, events
from locust.exception import StopUser
# ---------------------- 1. 全局初始化:加载测试用户数据 ----------------------
USER_LIST = []
def load_user_data():
"""从JSON文件加载测试用户数据(username)"""
try:
with open("test_users.json", "r", encoding="utf-8") as f:
data = json.load(f)
# 提取所有有效用户名,避免空值
user_names = [user["username"] for user in data if "username" in user and user["username"]]
print(f"成功加载 {len(user_names)} 个测试用户")
return user_names
except FileNotFoundError:
print("❌ 错误:未找到test_users.json文件,请确认文件路径")
return []
except json.JSONDecodeError:
print("❌ 错误:test_users.json格式无效,请检查JSON语法")
return []
# 初始化加载用户数据
USER_LIST = load_user_data()
# ---------------------- 2. 定义虚拟用户行为 ----------------------
class LoginUser(HttpUser):
"""登录接口虚拟用户类:模拟用户发起登录请求"""
# 被测系统基础地址(避免重复写完整URL)
host = "http://112.126.74.xxx"
# 每个用户执行完任务后,随机等待1-3秒(模拟真实用户操作间隔)
wait_time = between(1, 3)
def on_start(self):
"""用户启动时执行:随机选择一个测试用户,避免重复登录"""
if not USER_LIST:
print("❌ 无可用测试用户,停止当前虚拟用户")
raise StopUser() # 终止当前用户,避免无效请求
# 随机选一个用户,密码统一为user123(根据实际场景调整)
self.username = random.choice(USER_LIST)
self.password = "user123"
@task # 标记为核心测试任务
def login_api_test(self):
"""核心任务:调用登录接口,并验证响应结果"""
# 1. 定义接口地址(拼接host后完整地址:http://112.126.74.xxx/wx/auth/login)
url = "/wx/auth/login"
# 2. 设置请求头(模拟真实前端请求,按实际接口要求调整)
headers = {
"accept": "application/json, text/plain, */*",
"accept-encoding": "gzip, deflate",
"accept-language": "zh-CN,zh;q=0.9,en;q=0.8",
"content-type": "application/json",
"origin": "http://112.126.74.xxx",
"referer": "http://112.126.74.xxx/mall/",
"user-agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 18_5 like Mac OS X) AppleWebKit/605.1.15 KHTML, like Gecko Version/18.5 Mobile/15E148 Safari/604.1"
}
# 3. 构造请求体(使用随机选择的用户名)
payload = {
"username": self.username,
"password": self.password
}
# 4. 发送POST请求,并捕获响应(用于断言验证)
with self.client.post(
url=url,
json=payload, # 自动序列化JSON,无需手动转字符串
headers=headers,
catch_response=True, # 开启响应捕获,便于自定义断言
name="登录接口" # 测试报告中显示的任务名称,便于区分
) as response:
# 5. 响应结果断言(验证登录是否成功)
try:
res_json = response.json()
# 断言1:响应状态码为200
if response.status_code != 200:
response.failure(f"状态码错误:{response.status_code} | 用户:{self.username}")
# 断言2:响应errno为0(接口自定义成功标识)
elif res_json.get("errno") != 0:
response.failure(f"登录失败:{res_json.get('errmsg')} | 用户:{self.username}")
# 断言通过,标记为成功
else:
response.success()
# 异常处理:响应不是JSON格式
except json.JSONDecodeError:
response.failure(f"响应非JSON格式 | 用户:{self.username}")
# 其他未知异常
except Exception as e:
response.failure(f"处理响应出错:{str(e)} | 用户:{self.username}")
# ---------------------- 3. 测试生命周期钩子(可选) ----------------------
@events.test_start.add_listener
def on_test_start(environment, **kwargs):
"""测试开始时执行:打印测试信息"""
print(f"\n🚀 登录接口性能测试开始 | 测试用户数:{len(USER_LIST)}")
@events.test_stop.add_listener
def on_test_stop(environment,** kwargs):
"""测试结束时执行:打印测试总结"""
print("\n🛑 登录接口性能测试结束 | 请查看测试报告分析结果")3. 脚本核心说明
数据加载:通过
load_user_data函数读取test_users.json中的测试用户,避免硬编码账号,提升脚本灵活性;用户行为:
LoginUser类继承HttpUser,通过on_start初始化用户账号,@task标记登录任务;响应断言:开启
catch_response=True后,可自定义成功/失败判定规则,精准统计登录接口的错误率;生命周期钩子:
test_start/test_stop用于打印测试日志,方便排查问题。
四、运行Locust脚本
Locust支持两种运行方式:Web控制台模式(推荐新手) 和无界面模式(适合自动化)。
1. Web控制台模式(可视化操作)
在脚本所在目录执行命令:
locust -f login_perf_test.py执行成功后,终端会输出:
[2025-12-XX XX:XX:XX] INFO/locust.main: Starting web interface at http://localhost:8089打开浏览器访问http://localhost:8089,进入Locust控制台:
Number of users:总并发虚拟用户数(推荐填50,符合常规接口压测场景);
Spawn rate:每秒启动的用户数(推荐填5,10秒达到50并发,避免瞬间压垮服务器);
Host:被测系统地址(脚本中已定义,此处可留空);
点击「Start swarming」开始测试。
2. 无界面模式(适合CI/CD或后台运行)
如果不需要可视化控制台,可直接指定参数运行,测试结束后自动生成报告:
# 50并发用户,每秒启动5个,运行20分钟,无界面模式
locust -f login_perf_test.py --headless -u 50 -r 5 --run-time=20m核心参数说明:
五、分析测试结果
Locust Web控制台提供了4个核心标签页,重点关注前3个:
1. Statistics(统计概览)
核心指标解读(登录接口重点关注):
Request name:任务名称(此处为“登录接口”);
Requests/s:TPS(每秒处理的请求数),越高说明接口吞吐量越好;
Median:响应时间中位数(50%的请求响应时间),登录接口建议≤500ms;
95%ile:95%请求的响应时间(核心指标,反映绝大多数用户的体验);
Failure %:错误率,登录接口需控制为0%,否则说明接口存在问题。
2. Charts(趋势图表)
直观查看:
响应时间随并发的变化趋势;
TPS的波动情况;
虚拟用户数的增长曲线。
3. Failures(失败请求)
若存在失败请求,此处会列出具体原因(如“状态码错误”“登录失败”),便于定位接口问题。
六、Locust进阶技巧(可选)
参数化优化:除了从JSON读取数据,还可从CSV/数据库加载测试用户,提升数据多样性;
分布式压测:多台机器启动Locust,模拟10万+级并发(适合大型系统);
结果导出:将测试结果导出为CSV/HTML,便于后续分析和汇报;
自定义指标:添加响应时间、TPS的自定义监控,满足个性化需求。
七、总结
本文以登录接口为例,完整讲解了Locust的环境搭建、核心概念、脚本编写、运行方式和结果分析。核心要点回顾:
Locust基于Python,轻量且高并发,适合中小团队做接口性能测试;
核心逻辑是“定义虚拟用户类 + 标记测试任务 + 验证响应结果”;
运行时需合理设置并发数(-u)和启动速率(-r),避免测试结果失真;
登录接口重点关注95%响应时间和错误率,确保接口稳定性。
相比于传统性能测试工具,Locust的优势在于“简单、灵活、易扩展”,只要掌握基础Python语法,就能快速适配各类接口的性能测试场景。建议从简单接口(如登录、查询)入手,逐步尝试复杂场景(如下单、支付),快速掌握Locust的使用精髓。