一篇文章讲明白locust性能测试

本文涉及的产品
性能测试 PTS,5000VUM额度
简介: 一篇文章讲明白locust性能测试

1.web启动:

1)locust -f x.py --host=xxxxx.com

2)通过浏览器访问:

Number of users to simulate 设置虚拟用户数

Hatch rate(users spawned/second)每秒产生(启动)的虚拟用户数 , 点击Start swarming 按钮,开始运行性能测试。

2.no-web启动:

1)locust -f x.py --no-web --csv=result -c10 -r2 -t 1m

--no-web 表示不使用web界面运行测试

-c 设置虚拟用户数

-r 设置每秒启动虚拟用户数

-t 设置运行时间.

--csv=result将测试结果保存到当前.py目录中

3.分布式压测:

主从机中必须运行相同的测试代码(把主机中代码复制一份到多个从机中),主机负责收集测试数据,从机进行施压测试;

locust -f xxxoo.py --master

locust -f xxxoo.py --slave --master-host=master-ip

分布式压测no-web模式保存结果到主机中当前运行.py的目录中:]locust -f test2.py --csv=foobartt --no-web -c2 -t10s --master

实例脚本

伪代码:

from locust import HttpLocust, TaskSet, task

class WebsiteTasks(TaskSet):

def on_start(self): #进行初始化的工作,每个Locust用户开始做的第一件事

payload = {

"username": "test_user",

"password": "123456",

}

header = {

"User-Agent":"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36",

}

self.client.post("/login",data=payload,headers=header)#self.client属性使用Python request库的所有方法,调用和使用方法和requests完全一致;

@task(5) #通过@task()装饰的方法为一个事务,方法的参数用于指定该行为的执行权重,参数越大每次被虚拟用户执行的概率越高,默认为1

def index(self):

self.client.get("/")

@task(1)

def about(self):

self.client.get("/about/")

class WebsiteUser(HttpLocust):

host = "" #被测系统的host,在终端中启动locust时没有指定--host参数时才会用到

task_set = WebsiteTasks #TaskSet类,该类定义用户任务信息,必填。这里就是:WebsiteTasks类名,因为该类继承TaskSet;

min_wait = 5000 #每个用户执行两个任务间隔时间的上下限(毫秒),具体数值在上下限中随机取值,若不指定默认间隔时间固定为1秒

max_wait = 15000

4.WebsiteTasks类中调用 WebsiteUser(HttpLocust)类中定义的字段和方法:

通过在WebsiteTasks类中self.locust.xxoo xxoo就是我们在WebsiteUser类中定义的字段或方法;

伪代码:

from locust import HttpLocust, TaskSet, taskimport hashlibimport queue class WebsiteTasks(TaskSet): @task(5) def index(self): data = self.locust.user_data_queue #获取WebsiteUser里面定义的ser_data_queue队列 md5_data=self.locust.md5_encryption() #获取WebsiteUser里面定义的md5_encryption()方法 self.client.get("/") class WebsiteUser(HttpLocust): host = "" task_set = WebsiteTasks min_wait = 5000 max_wait = 15000 user_data_queue = queue.Queue() def md5_encryption(self,star): '''md5加密方法''' obj = hashlib.md5() obj.update(bytes(star,encoding="utf-8")) result = obj.hexdigest() return result

伪代码中测试场景如何表达?

代码主要包含两个类:

WebsiteUser继承(HttpLocust,而HttpLocust继承自Locust)

WebsiteTasks继承(TaskSet)

3. WebsiteTasks(TaskSet),继承TaskSet,该类下面写需要请求的接口以及相关信息;

self.client调用get和post方法,和requests一样;

4. @task装饰该方法表示为用户行为,括号里面参数表示该行为的执行权重:数值越大,执行频率越高,不设置默认是1;

5. WebsiteUser()类用于设置生成负载的基本属性:

6.Locust类中,除了client属性,还有几个属性需要关注:

task_set ---> 指向一个TaskSet类,TaskSet类定义了用户的任务信息,该静态字段为必填;

max_wait/min_wait ---> 每个用户执行两个任务间隔的上下限(毫秒),具体数值在上下限中随机取值,若不指定则默认间隔时间为1秒;

host --->被测试系统的host,当在终端中启动locust时没有指定--host参数时才会用到;

weight--->同时运行多个Locust类时,用于控制不同类型的任务执行权重;

7.Locust流程,测试开始后,每个虚拟用户(Locust实例)运行逻辑都会遵守如下规律:

先执行WebsiteTasks中的on_start(只执行一次),作为初始化;

从WebsiteTasks中随机挑选(如果定义了任务间的权重关系,那么就按照权重关系随机挑选)一个任务执行;

根据Locust类中min_wait和max_wait定义的间隔时间范围(如果TaskSet类中也定义了min_wait或者max_wait,以TaskSet中的优先),在时间范围中随机取一个值,休眠等待;

重复2~3步骤,直到测试任务终止;

8.关联

在某些请求中,需要携带之前response中提取的参数,常见场景就是session_id。Python中可用通过re正则匹配,对于返回的html页面,可用采用lxml库来定位获取需要的参数;

from locust import HttpLocust, TaskSet, task

from lxml import etree

class WebsiteTasks(TaskSet):

def get_session(self,html): #关联例子

tages = etree.html(html)

return tages.xpath("//div【@class='btnbox'】/input【@name='session'】/@value")【0】

def on_start(self):

html = self.client.get('/index')

session = self.get_session(html.text)

payload = {

"username": "test_user",

"password": "123456",

'session' : session

}

header = {

"User-Agent":"Mozilla/5.0 //代码效果参考:http://www.zidongmutanji.com/bxxx/487128.html

(Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36",

}

self.client.post("/login",data=payload,headers=header)

@task(5)

def index(self):

self.client.get("/")

assert response【'ErrorCode'】==0 #断言

@task(1)

def about(self):

self.client.get("/about/")

class WebsiteUser(HttpLocust):

host = ""

task_set = WebsiteTasks

min_wait = 5000

max_wait = 15000

9.参数化

循环取数据,数据可重复使用

例如:模拟3个用户并发请求网页,共有100个URL地址,每个虚拟用户都会依次循环加载100个URL地址

from locust import TaskSet, task, HttpLocustclass UserBehavior(TaskSet): def on_start(self): self.index = 0 @task def test_visit(self): url = self.locust.share_data【self.index】 print('visit url: %s' % url) self.index = (self.index +//代码效果参考:http://www.zidongmutanji.com/bxxx/343912.html

1) % len(self.locust.share_data) self.client.get(url)class WebsiteUser(HttpLocust): host = '' task_set = UserBehavior share_data = 【'url1', 'url2', 'url3', 'url4', 'url5'】 min_wait = 1000 max_wait = 3000

保证并发测试数据唯一性,不循环取数据;

所有并发虚拟用户共享同一份测试数据,并且保证虚拟用户使用的数据不重复;

例如:模拟3用户并发注册账号,共有9个账号,要求注册账号不重复,注册完毕后结束测试

采用队列

from locust import TaskSet, task, HttpLocustimport queueclass UserBehavior(TaskSet): @task def test_register(self): try: data = self.locust.user_data_queue.get() except queue.Empty: print('account data run out, test ended.') exit(0) print('register with user: {}, pwd: {}'\ .format(data【'username'】, data【'password'】)) payload = { 'username': data【'username'】, 'password': data【'password'】 } //代码效果参考:http://www.zidongmutanji.com/bxxx/244748.html

self.client.post('/register', data=payload)class WebsiteUser(HttpLocust): host = '' task_set = UserBehavior user_data_queue = queue.Queue() for index in range(100): data = { "username": "test%04d" % index, "password": "pwd%04d" % index, "email": "test%04d@debugtalk.test" % index, "phone": "186%08d" % index, } user_data_queue.put_nowait(data) min_wait = 1000 max_wait = 3000

保证并发测试数据唯一性,循环取数据;

所有并发虚拟用户共享同一份测试数据,保证并发虚拟用户使用的数据不重复,并且数据可循环重复使用;

例如:模拟3个用户并发登录账号,总共有9个账号,要求并发登录账号不相同,但数据可循环使用;

from locust import TaskSet, task, HttpLocustimport queueclass UserBehavior(TaskSet): @task def test_register(self): try: data = self.locust.user_data_queue.get() except queue.Empty: print('account data run out, test ended') exit(0) print('register with user: {0}, pwd: {1}' .format(data【'username'】, data【'password'】)) payload = { 'username': data【'username'】, 'password': data【'password'】 } self.client.post('/register', data=payload) self.locust.user_data_queue.put_nowait(data)class WebsiteUser(HttpLocust): host = '' task_set = UserBehavior user_data_queue = queue.Queue() for index in range(100): data = { "username": "test%04d" % index, "password": "pwd%04d" % index, "email": "test%04d@debugtalk.test" % index, "phone": "186%08d" % index, } user_data_queue.put_nowait(data) min_wait = 1000 max_wait = 3000

10.断言(即检查点)

通过with self.client.get("url地址",catch_response=True) as response的形式;

response.status_code获取http响应码进行判断,失败后会加到统计错误表中;

python自带的断言assert失败后代码就不会向下走,且失败后不会被Locust报表统计进去;

默认不写参数catch_response=False断言无效,将catch_response=True才生效;

下面例子中:

首先使用python断言对接口返回值进行判断(python断言不通过,代码就不向下执行,get请求数为0),通过后对该接口的http响应是否为200进行判断;

@task

def all_interface(self):

#豆瓣图书api为例子

with self.client.get("",name="/LhcActivity/GetActConfig",catch_response=True) as response:

assert response.json()【'rating'】【'max'】==10 #python断言对接口返回值中的max字段进行断言

if response.status_code ==200: #对http响应码是否200进行判断

response.success()

else:

response.failure("GetActConfig【Failed!】")

11.locust的UI界面

1、启动界面

Number of users to simulate:设置模拟的用户总数

Hatch rate (users spawned/second):每秒启动的虚拟用户数

Start swarming:执行locust脚本

2、测试结果界面

PS:点击STOP可以停止locust脚本运行:

Type:请求类型,即接口的请求方法;

Name:请求路径;

requests:当前已完成的请求数量;

fails:当前失败的数量;

Median:响应时间的中间值,即50%的响应时间在这个数值范围内,单位为毫秒;

Average:平均响应时间,单位为毫秒;

Min:最小响应时间,单位为毫秒;

Max:最大响应时间,单位为毫秒;

Content Size:所有请求的数据量,单位为字节;

reqs/sec:每秒钟处理请求的数量,即QPS;

3、各模块说明

New test:点击该按钮可对模拟的总虚拟用户数和每秒启动的虚拟用户数进行编辑;

Statistics:类似于jmeter中Listen的聚合报告;

Charts:测试结果变化趋势的曲线展示图,分别为每秒完成的请求数(RPS)、响应时间、不同时间的虚拟用户数;

Failures:失败请求的展示界面;

Exceptions:异常请求的展示界面;

Download Data:测试数据下载模块, 提供三种类型的CSV格式的下载,分别是:Statistics、responsetime、exceptions;

参考文档:

相关实践学习
通过性能测试PTS对云服务器ECS进行规格选择与性能压测
本文为您介绍如何利用性能测试PTS对云服务器ECS进行规格选择与性能压测。
相关文章
|
16天前
|
测试技术 持续交付 Apache
Python性能测试新风尚:JMeter遇上Locust,性能分析不再难🧐
【10月更文挑战第1天】Python性能测试新风尚:JMeter遇上Locust,性能分析不再难🧐
63 3
|
1月前
|
测试技术 数据库 UED
Python 性能测试进阶之路:JMeter 与 Locust 的强强联合,解锁性能极限
【9月更文挑战第9天】在数字化时代,确保软件系统在高并发场景下的稳定性至关重要。Python 为此提供了丰富的性能测试工具,如 JMeter 和 Locust。JMeter 可模拟复杂请求场景,而 Locust 则能更灵活地模拟真实用户行为。结合两者优势,可全面评估系统性能并优化瓶颈。例如,在电商网站促销期间,通过 JMeter 模拟大量登录请求并用 Locust 模拟用户浏览和购物行为,可有效识别并解决性能问题,从而提升系统稳定性和用户体验。这种组合为性能测试开辟了新道路,助力应对复杂挑战。
86 2
|
16天前
|
缓存 测试技术 Apache
告别卡顿!Python性能测试实战教程,JMeter&Locust带你秒懂性能优化💡
【10月更文挑战第1天】告别卡顿!Python性能测试实战教程,JMeter&Locust带你秒懂性能优化💡
45 4
|
18天前
locust网站压力测试软件
locust网站压力测试软件
26 0
|
1月前
|
测试技术 持续交付 Apache
Python性能测试新风尚:JMeter遇上Locust,性能分析不再难🧐
【9月更文挑战第10天】随着软件应用的不断扩展,性能测试成为确保系统稳定运行的关键环节。本文通过对比Apache JMeter和Locust,探讨了如何在Python环境中利用这两款工具挖掘更多性能测试潜力。JMeter是一款成熟且功能强大的开源工具,支持多种协议,适用于各种应用的测试;而Locust则基于Python,通过简单脚本模拟HTTP请求,更适合Web应用测试。
76 3
|
1月前
|
缓存 测试技术 Apache
告别卡顿!Python性能测试实战教程,JMeter&Locust带你秒懂性能优化💡
【9月更文挑战第5天】性能测试是确保应用在高负载下稳定运行的关键。本文介绍Apache JMeter和Locust两款常用性能测试工具,帮助识别并解决性能瓶颈。JMeter适用于测试静态和动态资源,而Locust则通过Python脚本模拟HTTP请求。文章详细讲解了安装、配置及使用方法,并提供了实战案例,帮助你掌握性能测试技巧,提升应用性能。通过分析测试结果、模拟并发、检查资源使用情况及代码优化,确保应用在高并发环境下表现优异。
62 5
|
1月前
|
消息中间件 监控 测试技术
惊呆了!Python性能测试高手都用这些神器:JMeter+Locust,效率翻倍📈
【9月更文挑战第8天】在软件开发中,性能测试对确保应用稳定性和高效运行至关重要。对于Python开发者而言,选择合适的性能测试工具能显著提升测试效率并精准定位性能瓶颈。本文深入探讨了JMeter和Locust这两款工具的独特优势。JMeter作为跨平台的性能测试工具,支持多种协议,具备高度可定制性和扩展性;而Locust则专为Python应用设计,利用协程实现高并发,提供实时监控和分布式测试功能。两者结合使用,可在实际项目中实现1+1>2的效果,帮助开发者构建全面高效的测试方案,保障应用稳定运行。
107 1
|
1月前
|
测试技术 Apache 数据库
从慢如蜗牛到飞一般的感觉!Python性能测试实战,JMeter&Locust助你加速🏃‍♂️
【9月更文挑战第6天】你的Python应用是否曾因响应缓慢而让用户望而却步?借助JMeter与Locust,这一切将迎刃而解。JMeter作为Apache基金会的明星项目,以其强大的跨平台和多协议支持能力,成为性能测试领域的魔法师;而Locust则以Python的简洁与高效,让性能测试更加灵活。通过实战演练,你可以利用这两款工具轻松识别并解决性能瓶颈,优化数据库查询、网络配置等,最终使应用变得敏捷高效,轻松应对高并发挑战。
23 1
|
9天前
|
JSON 算法 数据可视化
测试专项笔记(一): 通过算法能力接口返回的检测结果完成相关指标的计算(目标检测)
这篇文章是关于如何通过算法接口返回的目标检测结果来计算性能指标的笔记。它涵盖了任务描述、指标分析(包括TP、FP、FN、TN、精准率和召回率),接口处理,数据集处理,以及如何使用实用工具进行文件操作和数据可视化。文章还提供了一些Python代码示例,用于处理图像文件、转换数据格式以及计算目标检测的性能指标。
18 0
测试专项笔记(一): 通过算法能力接口返回的检测结果完成相关指标的计算(目标检测)
|
1月前
|
移动开发 JSON Java
Jmeter实现WebSocket协议的接口测试方法
WebSocket协议是HTML5的一种新协议,实现了浏览器与服务器之间的全双工通信。通过简单的握手动作,双方可直接传输数据。其优势包括极小的头部开销和服务器推送功能。使用JMeter进行WebSocket接口和性能测试时,需安装特定插件并配置相关参数,如服务器地址、端口号等,还可通过CSV文件实现参数化,以满足不同测试需求。
167 7
Jmeter实现WebSocket协议的接口测试方法