locust接口压测
文档
文档:https://docs.locust.io/en/stable/
安装
1.安装python3.7以上版本
2.安装包: pip install locust
3.验证: locust -V
编写locustfile
import os
from locust import TaskSet, HttpUser, task, between
class BaiduTaskSet(TaskSet):
"""任务集"""
@task
def visit_index(self):
with self.client.get(url='/', name='访问首页', catch_response=True) as resp:
# 响应断言
if resp.status_code == 200:
resp.success()
else:
resp.failure(f"状态码:{resp.status_code}")
class BaiduUser(HttpUser):
tasks = [BaiduTaskSet, ]
host = 'http://www.baidu.com'
wait_time = between(3, 5)
if __name__ == '__main__':
os.system("locust -f locustfile.py --web-host=127.0.0.1")
脚本主要包含两个类:BaiduTaskSet和BaiduUser,BaiduTaskSet继承TaskSet,BaiduUser继承HttpUser(HttpUser继承User)。
BaiduTaskSet是定义用户执行的任务细节,而BaiduUser(User)则是负责生成用户实例去执行这些任务。
定义任务:
1.使用@task装饰(注释则不会执行)。
2.client是基于requests.session封装的,请求和响应的方法属性和requests相同。
3.需要对响应断言:使用with语句+catch_response=True
运行脚本,在浏览器打开:http://127.0.0.1:8089
输入并发用户数量,每秒启动的用户数量,点击开始测试。
测试结果可在download data页面下载。
测试场景1
循环取数据,数据可重复使用: 模拟10用户并发请求网页,总共有100个URL地址,每个虚拟用户都会依次循环加载这100个URL地址
import os
import queue
from locust import HttpUser, between, TaskSet, task
class BaiduTaskSet(TaskSet):
@task
def visit_index(self):
url = self.parent.url_data.pop(0)
print(url)
self.parent.url_data.append(url)
with self.client.get(url=url, name='访问首页', catch_response=True) as resp:
if resp.status_code == 200:
resp.success()
else:
resp.failure(f"状态码:{resp.status_code}")
def url_data():
url = "https://www.baidu.com/s?wd={}"
return [url.format(i) for i in range(100)]
class BaiduUser(HttpUser):
tasks = [BaiduTaskSet, ]
host = 'http://www.baidu.com'
wait_time = between(3, 5)
url_data = url_data()
说明:在User类定义数据-列表类型,在TaskSet中使用self.parent.url_data.pop(0)取数据,使用append将数据放回。
测试场景2
保证并发测试数据唯一性,不循环取数据: 模拟10用户并发请求网页,总共有100个URL地址,要求访问网页不重复,访问完毕后结束测试
import os
import queue
from locust import HttpUser, between, TaskSet, task
class BaiduTaskSet(TaskSet):
"""任务集"""
@task
def visit_index(self):
url = self.parent.url_data.get()
print(url)
with self.client.get(url=url, name='访问首页', catch_response=True) as resp:
# 响应断言
if resp.status_code == 200:
resp.success()
else:
resp.failure(f"状态码:{resp.status_code}")
def url_data():
url = "https://www.baidu.com/s?wd={}"
q = queue.Queue()
for i in [url.format(i) for i in range(100)]:
q.put_nowait(i)
return q
class BaiduUser(HttpUser):
tasks = [BaiduTaskSet, ]
host = 'http://www.baidu.com'
wait_time = between(3, 5)
url_data = url_data()
说明:在User类定义数据-队列类型(queue),在TaskSet中使用self.parent.url_data.get()取数据,
测试场景3
保证并发测试数据唯一性,循环取数据: 模拟10用户并发请求网页,总共有100个URL地址,要求访问网页不重复,但数据可循环使用。
在场景2基础上添加代码: self.parent.url_data.put_nowait(url),取完数据后放回。
无界面运行
os.system("locust -f locustfile.py --headless --csv=test_result -u 30 -r 5 -t 600")
–csv :测试结果输出路径
-u: 并发数
-r: 每秒启动用户数
-t: 运行时间
封装WebSocketClient
from websocket import create_connection
WS_HOST = 'wss://xxx.xxx.xx'
class WebSocketClient(object):
"""封装websocketclient"""
def __init__(self):
self.ws_host = WS_HOST
@staticmethod
def error(start_time, error, name='进度条'):
total_time = int((time.time() - start_time) * 1000)
events.request_failure.fire(request_type="websocket", name=name, response_time=total_time, exception=error,
response_length=0)
@staticmethod
def success(start_time, name='进度条'):
total_time = int((time.time() - start_time) * 1000)
events.request_success.fire(request_type="websocket", name=name, response_time=total_time,
response_length=0)
def send_ws(self, payload, url="/app/progressbar", name='进度条', **kwargs):
"""建立连接"""
start_time = time.time()
process = None
header = dict(**kwargs).get('headers')
try:
ws = create_connection(self.ws_host + url, header=header)
except Exception as e:
self.error(start_time, e, name=name)
else:
if ws.connected:
ws.send(payload=payload)
while True:
time.sleep(2)
resp = json.loads(ws.recv())
if resp['code'] != 200:
self.error(start_time, error=resp, name=name)
break
process = int(resp["data"]["progress"])
# print(process)
if resp['data']['status'] != 2:
ws.close()
break
if process == 100:
self.success(start_time, name=name)
else:
# print(resp)
self.error(start_time, error=resp, name=name)
测试非HTTP请求
安装插件:pip install locust-plugins
可测试WebSocket/SocketIO, Kafka, Selenium/WebDriver等
使用参考:
https://docs.locust.io/en/stable/testing-other-systems.html#
https://github.com/SvenskaSpel/locust-plugins#users