性能测试利器-Locust框架解析
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了性能测试利器-Locust框架解析相关的知识,希望对你有一定的参考价值。
参考技术A本文章出自【码同学软件测试】
码同学公众号:自动化软件测试
码同学抖音号:小码哥聊软件测试
1
认识Locust
说起性能测试工具,大家肯定想到的都是Jmeter,是的,由于其简单易用、功能强大,已经变成主流的压测工具之一。当需要实现一些高级功能的时候,可以使用Java语言对Jmeter进行扩展。
但是很多小伙伴只会Python,不会Java,可不可使用Python语言来做性能测试呢?答案是肯定的,今我们就来介绍下基于Python的强大的性能测试框架Locust。
Locust直译是“蝗虫”的意思,意在压测时产生的压力就像是漫天蝗虫一样,铺天盖地。Locust是用Python实现的开源性能测试框架,不同于其他压测工具基于进程/线程产生压力,Locust是完全基于事件,支持分布式,一个Locust节点可以在一个进程中轻松支持上千并发用户。从这一点来看,它的设计思路要远优于Jmeter、Loadrunner之类的工具。
2
Locust环境搭建
1、安装Python,建议使用Python3.6+
2、安装Locust及其依赖:pip3 install -i https://pypi.douban.com/simple locust
3、验证是否安装成功,执行命令:locust -V,如果能看到版本信息,即代表安装成功
3
Locust脚本编写
不同于Jmeter的界面化脚本配置,Locust的脚本需要完全写Python代码,虽然从一定程度提高了脚本编 写的门槛,但是对于熟悉Python的人来说还是比较简单的,况且自己写代码的话,脚本的灵活性更高。
Locust脚本就是一个普通的Python文件,但是在脚本中必须先定义一个类,然后继承Locust提供的一个HttpUser类。在测试类里,将压测的请求封装到一个函数里,一个简单的Locust脚本就完成了。
看个实际的例子,比如现在要测试这样一个接口
URL: http://192.168.2.130:8080/pinter/login
参数:userName=admin&password=1234
在上面脚本中,login_test是自定义的测试函数,函数上添加了一个装饰器@task,标明此函数是需要
Locust并发执行。在函数内调用了父类的client对象中post方法,发起了一次HTTP post请求。
在MyTest类里,必须添加一个wait_time属性,此属性设置了循环调用login_test之间的等待时间,
between(1,1)代表等待时间为1秒
4
Locust脚本运行
免费领取 码同学软件测试 课程笔记+超多学习资料+完整视频+最新面试题,可以 转发文章 + 私信「码同学666」获取资料哦
脚本写好后,需要在命令行上去运行Locust脚本,在cmd下(或者Mac的终端、Linux命令行),进入到脚本目录,执行命令
然后在浏览器上访问URL: http://localhost:8089/ ,就可以打开Locust的压测控制页面
5
Locust压测执行
在Locust的压测控制页面打开后,就可以针对脚本做一些压测的配置了,比如并发数,压测持续时间,
host等,其中:
Number of total users to simulate: 并发数,代表模拟了多少虚拟用户
Hatch rate: 每秒产生的用户数
Host: 目标服务器的ip或域名
点击"Start swarming",即可开始压测,在web页面会上统计出实时的性能汇总数据
字段解释
TPS和响应时间曲线图
好啦,关于Locust的入门,今天就介绍这么多啦,后续会继续介绍Locust的高级特性和详细功能,敬请期待!
本文著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。
Python Locust性能测试框架实践
[本文出自天外归云的博客园]
Locust的介绍
Locust是一个python的性能测试工具,你可以通过写python脚本的方式来对web接口进行负载测试。
Locust的安装
首先你要安装python2.6以上版本,而且有pip工具。之后打开命令行,分别安装locustio和pyzmq(命令如下):
pip install locustio pip install pyzmq
之后我们就可以写性能测试脚本了。
Locust脚本编写
接下来我们拿两个接口做一下测试,编写脚本如下(每一步都有注释)。我来解释一下,首先我们要import进来三个类,分别是HttpLocust(用来模拟发请求的类)、TaskSet(顾名思义,任务集)、task(任务类)。额外的,为了方便观察接口测试的执行结果,我引入了json类用来解析web接口的返回值。我还引入了subprocess类用来执行一下shell命令,自启动Locust。这里有三个类,一个是UserBehavior(名字随便起,但传入TaskSet参数,说明这是一个包含了任务集的类),里面on_start函数可有可无,他会先于所有task函数运行。剩下被@task装饰器装饰的方法都是任务方法,里面包含了待请求的接口等信息,传入的参数代表了权重,如下所示两个被@task装饰的方法分别传入1和2,这意味着每3个人里有两个人会有1个模拟用户执行list_header方法,2个模拟用户执行list_goods方法。这个参数你也可以不传入,那就意味着模拟用户会随机访问所有被@task装饰的方法。这里面我对于每个接口的返回值都做了一下判断,首先将返回的字符串转成json格式并获取返回字段result的值,如果不是100就用Locust自带的报错方法打印出错信息;另两个类是HttpLocust类(仍然是名字随便起但传入参数必须得是HttpLocust),是用来模拟用户的类,包含了一些模拟用户信息,其中task_set变量的值用来指定模拟用户所对应要完成的TaskSet类中包含的请求,min_wait和max_wait(最小等待时间和最大等待时间用来模拟用户每两步操作之间的间隔时间,这里也就是模拟用户每执行两个请求之间所间隔的时间)。对Locust类我们可以指定权重,对weight变量的值进行指定。如下所示,两个Locust类的权重分别为1和3,这意味着两个Locust类的模拟用户人数为1:3的关系。最后我加了一个main函数用来执行shell命令,这个shell命令也可以不再本文件中执行,如果写在脚本中的话,直接在命令行中调用该python文件即可,如果不写在脚本中(注释掉最后两行),则需要在命令行终端里对Locust项目进行启动。
from locust import HttpLocust,TaskSet,task import subprocess import json #This is the TaskSet class. class UserBehavior(TaskSet): #Execute before any task. def on_start(self): pass #the @task takes an optional weight argument. @task(1) def list_header(self): r = self.client.get("/homepage/list_header.html") if json.loads((r.content))["result"] != 100: r.failure("Got wrong response:"+r.content) @task(2) def list_goods(self): r = self.client.get("/homepage/list_goods.html") if json.loads((r.content))["result"] != 100: r.failure("Got wrong response:"+r.content) #This is one HttpLocust class. class WebUserLocust(HttpLocust): #Speicify the weight of the locust. weight = 1 #The taskset class name is the value of the task_set. task_set = UserBehavior #Wait time between the execution of tasks. min_wait = 5000 max_wait = 15000 #This is another HttpLocust class. class MobileUserLocust(HttpLocust): weight = 3 task_set = UserBehavior min_wait = 3000 max_wait = 6000 #if __name__ == ‘__main__‘: # subprocess.Popen(‘locust -f .\\locust_test_1.py --host=http://api.g.caipiao.163.com‘, shell=True)
Locust的启动
对Locust项目的启动,我们可以在命令行终端中执行以下命令:
locust -f .\\locust_test_1.py --host=http://api.g.caipiao.163.com
这里的“-f”指定了要执行的python文件路径,“--host”指定了模拟用户请求接口的host名。执行该命令,Locust项目就启动了。如果遇到下面的错误,注意[Errorno 10048]那行,可以看出端口8089被占用导致Locust项目启动失败,这里我们需要找到对应占用了8089端口的进程并杀掉:
为了检测占用端口的进程我写了一个PowerShell小脚本:
function checkPid($result,$port){ $port = $port.split(":")[1] if(($result.split())[6].split(":")[($result.split())[6].split(":").Count-1] -eq $port){ $tPid = ($result.split())[($result.split()).count-1] if($tPid -ne "0"){ Write-Host "您查询的端口被以下程序占用:" -ForegroundColor Red $target = tasklist|findstr $tPid Write-Host $target $sig = $true }else{ $sig = $false } }else{ $sig = $false } $sig } function checkPort($port){ $port = ":" + $port $results = netstat -ano|findstr $port if($results.count -gt 0){ if($results.count -eq 1){ $sig = checkPid $results $port if($sig -eq $false){ Write-Host "您所查询的端口未被占用!" -ForegroundColor Green } }else{ foreach($result in $results){ if($result){ $sig = checkPid $result $port if($sig -eq $true){ break } } } if($sig -eq $false){ Write-Host "您所查询的端口未被占用!" -ForegroundColor Green } } }else{ Write-Host "您所查询的端口未被占用!" -ForegroundColor Green } } $port = $null while($port -ne "exit()"){ $port = Read-Host "请输入要查询的端口号" if($port -eq "exit()"){ break } checkPort $port }
运行该脚本,输入端口号8089我们可以看出python.exe进程占用了该端口号:
然后我们在PowerShell中杀掉该进程,再启动Locust项目,就成功了(如下):
Locust负载测试
在浏览器中输入“http://localhost:8089/”访问,会看到如下页面:
这里我们按提示输入要模拟的用户总数和每秒钟并发的用户数量,点击“Start swarming”就可以运行负载测试了:
点击“STOP”按钮停止负载测试,现在STATUS为“STOPPED”,点击“New test”可以进行一个新的测试:
从上图可以看出在Statistics标签下列出了一些性能相关的测试结果,比如总的请求数量、请求失败的个数、每秒钟的请求数、最小\\最大响应时间、平均响应时间等。右上角显示了请求失败率和总的RPS(每秒钟请求数)。对应在Statistic右侧的Failures、Exceptions、Download Data标签下我们分别可以查看失败的请求、捕获的异常以及下载测试结果。这里不做过多介绍了,可以实际应用看一下。如果想深入的了解Locust性能测试框架,去官网上看看吧。
以上是关于性能测试利器-Locust框架解析的主要内容,如果未能解决你的问题,请参考以下文章