一篇文章讲明白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进行规格选择与性能压测。
相关文章
|
1月前
|
测试技术 持续交付 Apache
Python性能测试新风尚:JMeter遇上Locust,性能分析不再难🧐
【10月更文挑战第1天】Python性能测试新风尚:JMeter遇上Locust,性能分析不再难🧐
130 3
|
2月前
|
测试技术 数据库 UED
Python 性能测试进阶之路:JMeter 与 Locust 的强强联合,解锁性能极限
【9月更文挑战第9天】在数字化时代,确保软件系统在高并发场景下的稳定性至关重要。Python 为此提供了丰富的性能测试工具,如 JMeter 和 Locust。JMeter 可模拟复杂请求场景,而 Locust 则能更灵活地模拟真实用户行为。结合两者优势,可全面评估系统性能并优化瓶颈。例如,在电商网站促销期间,通过 JMeter 模拟大量登录请求并用 Locust 模拟用户浏览和购物行为,可有效识别并解决性能问题,从而提升系统稳定性和用户体验。这种组合为性能测试开辟了新道路,助力应对复杂挑战。
107 2
|
12天前
|
测试技术 持续交付 Apache
Python性能测试新风尚:JMeter遇上Locust,性能分析不再难🧐
Python性能测试新风尚:JMeter遇上Locust,性能分析不再难🧐
37 3
|
11天前
|
缓存 测试技术 Apache
告别卡顿!Python性能测试实战教程,JMeter&Locust带你秒懂性能优化💡
告别卡顿!Python性能测试实战教程,JMeter&Locust带你秒懂性能优化💡
25 1
|
1月前
|
缓存 测试技术 Apache
告别卡顿!Python性能测试实战教程,JMeter&Locust带你秒懂性能优化💡
【10月更文挑战第1天】告别卡顿!Python性能测试实战教程,JMeter&Locust带你秒懂性能优化💡
60 4
|
1月前
locust网站压力测试软件
locust网站压力测试软件
34 0
|
2月前
|
测试技术 持续交付 Apache
Python性能测试新风尚:JMeter遇上Locust,性能分析不再难🧐
【9月更文挑战第10天】随着软件应用的不断扩展,性能测试成为确保系统稳定运行的关键环节。本文通过对比Apache JMeter和Locust,探讨了如何在Python环境中利用这两款工具挖掘更多性能测试潜力。JMeter是一款成熟且功能强大的开源工具,支持多种协议,适用于各种应用的测试;而Locust则基于Python,通过简单脚本模拟HTTP请求,更适合Web应用测试。
92 3
|
2月前
|
消息中间件 监控 测试技术
惊呆了!Python性能测试高手都用这些神器:JMeter+Locust,效率翻倍📈
【9月更文挑战第8天】在软件开发中,性能测试对确保应用稳定性和高效运行至关重要。对于Python开发者而言,选择合适的性能测试工具能显著提升测试效率并精准定位性能瓶颈。本文深入探讨了JMeter和Locust这两款工具的独特优势。JMeter作为跨平台的性能测试工具,支持多种协议,具备高度可定制性和扩展性;而Locust则专为Python应用设计,利用协程实现高并发,提供实时监控和分布式测试功能。两者结合使用,可在实际项目中实现1+1>2的效果,帮助开发者构建全面高效的测试方案,保障应用稳定运行。
175 1
|
3月前
|
测试技术 持续交付 Apache
深度挖掘:Python性能测试中JMeter与Locust的隐藏技能🔍
【8月更文挑战第5天】随着软件规模扩大,性能测试对系统稳定性至关重要。Apache JMeter和Locust是两大主流工具,各有千秋。本文探索它们在Python环境下的进阶用法,挖掘更多性能测试潜力。JMeter功能强大,支持多种协议,可通过命令行模式执行复杂测试计划,并与Python集成实现动态测试数据生成。Locust基于Python,通过编写简洁脚本模拟HTTP请求,支持自定义请求及与Python库深度集成。掌握这些技巧可实现高度定制化测试场景,有效识别性能瓶颈,提升应用稳定性。
126 1
|
3月前
|
缓存 测试技术 Apache
告别卡顿!Python性能测试实战教程,JMeter&Locust带你秒懂性能优化💡
【8月更文挑战第5天】性能测试确保应用高负载下稳定运行。Apache JMeter与Locust是两大利器,助力识别解决性能瓶颈。本文介绍这两款工具的应用与优化技巧,并通过实战示例展示性能测试流程。首先,通过JMeter测试静态与动态资源;接着,利用Locust的Python脚本模拟HTTP请求。文中提供安装指南、命令行运行示例与性能优化建议,帮助读者掌握性能测试核心技能。
129 0