Python实现性能测试(locust)

news2024/11/26 4:51:45

一、安装locust

pip install locust -- 安装(在pycharm里面安装或cmd命令行安装都可

locust -V -- 查看版本,显示了就证明安装成功了

或者直接在Pycharm中安装locust:

搜索locust并点击安装,其他的第三方包也可以通过这种方式

二、locust介绍

Locust 是一种易于使用、可编写脚本且可扩展的性能测试工具。并且有一个用户友好的 Web 界面,可以实时显示测试进度。甚至可以在测试运行时更改负载。它也可以在没有 UI 的情况下运行,使其易于用于 CI/CD 测试。

Locust 使运行分布在多台机器上的负载测试变得容易。Locust 基于事件(gevent),因此可以在一台计算机上支持数千个并发用户。与许多其他基于事件的应用程序相比,它不使用回调。相反,它通过gevent使用轻量级进程。并发访问站点的每个Locust(蝗虫)实际上都在其自己的进程中运行(Greenlet)。这使用户可以在Python中编写非常有表现力的场景,而不必使用回调或其他机制。

三、脚本

1.方式一(直接在HttpUser中定义任务)

from locust import HttpUser, task, constant

class FlashUser(HttpUser):

host = 'http://127.0.0.1:8080/'

wait_time = constant(1)

@task

def login_test(self):

url = '/api/user/login'

data = {"userName":"xuyang@test.ai","password":"xy123456"}

headers = {"Content-Type": "application/json"}

self.client.request(method='POST', url=url, data=data, headers=headers, name='login登录')

HttpUser:控制用户发请求的频率、用户的思考时间、设置主机的IP地址、也可以定义任务

@task:@task用来标记哪个方法是任务,什么任务,我要做性能测试执行哪个接口

host:被测系统,你要发送请求到哪个服务器

wait_time:每次请求的间隔、停顿时间、思考时间

constant:为固定的思考时间,这里可以简单理解为固定定时器(只是wait_time的其中一种等待时间的方式,其它的可以自己研究一下)

描述:

1.创建一个User类FalshUser, 继承HttpUser,然后定义主机IP地址、思考时间;

2.在类下面编写一个测试接口,跟我们使用request类似,有个别区别;

3.用@task的方式进行定义任务,这个为什么要用task上面解释说了

4.接口方法内需要注意的点:

1)url只需要写路径即可,请求时自动拼接host;

2)发送请求的时候要用self.client.request去请求,并且增加method,和name两个入参,method就是请求方法、name就是接口名称;

3)self.client.request 它的发送请求跟我们常用的接口测试的request库非常类似,因为底层封装的就是request库;

运行描述:

打开你的Terminal,然后cd到你写的测试文件目录下,.py的文件;

运行命令:locust -f 测试文件.py

回车运行,之后如果出现第一张图显示的那样,就证明运行成功了;

打开你的浏览器输入http://localhost:8089,回车就会打开第二张图显示的GUI的locust页面

locust页面字段解释:

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

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

host:就是你脚本内写的被测系统地址,打开页面后自动填入的;

Start swarming:开始运行性能测试;

输入模拟的用户总数、输入每秒启动的虚拟用户数,点击Start swarming即可运行

运行结果:

大概就是这样,可以看类似jmeter聚合报告一样的表格,和tps监测、IO监测、可以导出各种类型的测试报告

2.方式二(写在模块内

from locust import HttpUser, task, constant

@task

def my_self_api(user):

url = '/api/user/login'

data = {"userName":"xuyang@test.ai","password":"xy123456"}

headers = {"Content-Type": "application/json"}

# 可以通过user.去调用client

user.client.request(method='POST', url=url, data=data, headers=headers, name='login登录')

class FlashUser(HttpUser):

host = 'http://127.0.0.1:8080/' # 被测系统的地址

wait_time = constant(1) # 每次请求的间隔、停顿时间、LR里面叫做思考时间(constant为固定的思考时间)

tasks = [my_self_api]

描述:

跟方式一代码类似,把User类和任务方法剥离,单独写开,用户操作用FlashUser管理,方法单独管理;

其中任务类剥离后,需要传入一个user字段,我们需要在任务函数里面来通过HttpUser传入的实例self->user来进行调用请求,需要注意我们任务函数传入的这个user,这个user就是FlashUser对象本身,就是FlashUser的一个实例,user指的就是self,这个时候我们就可以通过user.client来请求接口;

tasks解释:定义测试的范围,而测试方法的定义,可以放在测试类的外部,也就说可以用包去管理测试的方法,而真正要测试的时候,引入业务包,然后配置tasks即可,所以[ ]内我传了我写的任务名称,就是说我要执行这个任务,不然User不知道执行谁;

运行方式参考方式一GUI模式运行

3.方式三(把任务写在任务集里面)

from locust import HttpUser, constant, task, TaskSet

class TaskApi(TaskSet):

@task(1)

def login1(self):

url = '/api/user/login'

data = {"userName": "xuyang@test.ai", "password": "xy123456"}

headers = {"Content-Type": "application/json"}

self.client.request(method='POST', url=url, json=data, headers=headers, name='login-登录接口1')

@task(2)

def login2(self):

url = '/api/user/login'

data = {"userName": "xuyang@test.ai", "password": "xy123456"}

headers = {"Content-Type": "application/json"}

self.client.request(method='POST', url=url, json=data, headers=headers, name='login-登录接口2')

class FlashUser(HttpUser):

host = 'http://127.0.0.1:8080/'

wait_time = constant(2)

tasks = [TaskApi]

描述:

TaskSet解释:任务集,所谓的任务集,我理解的就是我有很多的性能测试任务/接口,那么我可以把这些接口写在一个类里面,和User类剥离出来,用User类来控制用户数和条件去进行执行;

方式三我把任务方法做了升级,写了一个TaskApi类,通过继承TaskSet来管理我的任务,这个类我主要写一些测试任务,每个需要执行性能测试的任务用@task标记;

那么代码怎么知道哪个是任务集呢?用TaskSet,需要作为任务集的类TaskApi,继承TaskSet,这样User类就知道,这个是任务集的类;

@task(1)、@task(2)里面的数字是什么意思?@task用来标记哪个方法是任务,括号里面的数字,我理解的是任务权重,比如:1、2,那么可以理解为如果用户有9个,那么@task(1)执行3个,@task(2)执行6个;

关于self.client:当我们在任务集的类中去写发送请求的时候,会发现self.后会出现user,这个user就是User类的实例,也就是说User类让哪个任务去执行,它就会把它自己的对象传给任务本身,当然你可以不写self.user, 直接self.client,当我们写了self.client后,ctrl+鼠标左键点击client,进去client底层方法会发现,它底层封装的是self.user.client;

注意:以上三种方式在执行性能测试的任务的时候,凡是带@task的标签的任务都是是并行运行的、是无序的,而不是按照代码逻辑从上往下执行

4.方式四(SequentialTaskSet)

SequentialTaskSet:如果需要有序的,我们可以继承该方法来进行创建任务

"""按顺序运行"""

class SeqSupTech(SequentialTaskSet):

url = '/api/user/login'

data = {"userName": "xuyang@test.ai", "password": "xy123456"}

headers = {"Content-Type": "application/json"}

@task(1)

def login1(self):

self.client.request(method="POST", url=self.url, json=self.data, headers=self.headers, name='登录接口1')

@task(5)

def login2(self):

self.client.request(method="POST", url=self.url, json=self.data, headers=self.headers, name='登录接口2')

class RequestUser(HttpUser):

host = 'http://127.0.0.1:8080/'

wait_time = constant(2)

tasks = [SeqSupTech]

描述:

只需要在创建任务集的类的时候继承SequentialTaskSet,那么这个任务集在运行的时候就会按照上下组合的顺序根据权重进行执行,比如上面这段代码的@task(1)和@task(5),代表先执行login1,再执行login2,循环执行;

四、非GUI模式运行并生成Html报告

命令:

locust -f denom_chain_query.py --headless -u 1 -r 1 -t 1m --html locust_report.html

-f locust_test.py //代表执行哪一个压测脚本

--headless //代表无界面执行

-u 100 //模拟100个用户操作

-r 100 //每秒用户增长数

-t 10m //压测10分钟

--html report.html //html结果输出的文件路径名称,无需提前创建,自动生成

运行:

Html报告:

最后建议接口传参的name用英文的,不要汉字,容易乱码,这个问题有解决的,可以在评论区讲下,我也学习一下

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/403174.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

JavaScript Math(算数)对象

Math(算数)对象的作用是:执行常见的算数任务。在线实例round()如何使用 round()。random()如何使用 random() 来返回 0 到 1 之间的随机数。max()如何使用 max() 来返回两个给定的数中的较大的数。(在 ECMASCript v3 之前&#xf…

站外seo优化有用吗?值得投入时间和精力吗?

随着互联网的普及和竞争的激烈化,SEO(Search Engine Optimization,搜索引擎优化)已经成为各种网站推广的必备技能。 而站外SEO优化就是指通过在其他网站上增加链接和引用等方式,来提高自己网站的搜索引擎排名和曝光度…

【6G 新技术】6G数据面介绍

博主未授权任何人或组织机构转载博主任何原创文章,感谢各位对原创的支持! 博主链接 本人就职于国际知名终端厂商,负责modem芯片研发。 在5G早期负责终端数据业务层、核心网相关的开发工作,目前牵头6G算力网络技术标准研究。 博客…

window.onresize的详细使用

最近做的项目老是涉及到大小屏切换,但是因为屏幕宽高不一样的原因,老是要计算表格高度 window.onresize:监听window窗口变化,当窗口大小发生变化时,会触发此事件 含义 MDN中的定义是这样子的: 文档视图调…

GitHub与PicGo搭建免费稳定图床并实现Typora内复制自动上传

本文介绍基于Github平台与PicGo工具,构建免费、稳定的图床,并实现在Typora内撰写Markdown文档时,粘贴图片就可以将这一图片自动上传到搭建好的图床中的方法。 1 配置GitHub 首先,我们需要配置Github,创建一个仓库从而…

mysql 查询一个表的数据,并修改部分数据,再插回原来的表中,复制某个用户的数据给另一个用户

mysql 查询一个表的数据,并修改部分数据,再插回原来的表中,复制某个用户的数据给另一个用户 一、需求 我有一表日记的表,表中盛放着所有用户的日记数据。 在做演示项目的时候,我需要将一个用户的数据复制给另一个用户…

PlotNeuralNet + ChatGPT创建专业的神经网络的可视化图形

PlotNeuralNet:可以创建任何神经网络的可视化图表,并且这个LaTeX包有Python接口,我们可以方便的调用。 但是他的最大问题是需要我们手动的编写网络的结构,这是一个很麻烦的事情,这时 ChatGPT 就出来了,它可…

JavaScript学习笔记(3.0)

数组是一种特殊类型的对象。在JavaScript中对数组使用typeof运算符会返回“object”。 但是&#xff0c;JavaScript数组最好以数组来描述。 数组使用数字来访问其“元素”。比如person[0]访问person数组中的第一个元素。 <!DOCTYPE html> <html> <body>&l…

【JavaEE进阶】——第一节.Maven国内源配置

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言 操作步骤 1.打开项目配置界面&#xff08;当前项目配置&#xff09; 2.检查并配置国内源 3.再次打开项目配置界面&#xff08;新项目配置&#xff09; 4…

Android RecyclerView的notify方法和动画的刷新详解

前些天发现了一个蛮有意思的人工智能学习网站,8个字形容一下"通俗易懂&#xff0c;风趣幽默"&#xff0c;感觉非常有意思,忍不住分享一下给大家。 &#x1f449;点击跳转到教程 前言&#xff1a; 本篇讲解了RecyclerView关于通知列表刷新的常用的notify方法。和Recy…

综合练习7 摄氏度转华氏温度(“\t“的使用,循环语句)

综合练习7 摄氏度转华氏温度 使用do…while循环&#xff0c;在控制台输入摄氏温度与华氏温度的对照表。 对照表从摄氏温度-30℃到50℃&#xff0c;每行间隔10℃&#xff0c;运行如下&#xff1a; 摄氏温度&#xff1a;-30℃ 华氏温度&#xff1a;-22.0℉ 摄氏温度&#xff1a;…

【专项训练】动态规划-3

动态规划:状态转移方程、找重复性和最优子结构 分治 + 记忆化搜索,可以过度到动态规划(动态递推) function DP():# DP状态定义# 需要经验,需把现实问题定义为一个数组,一维、二维、三维……dp =[][] # 二维情况for i = 0...M:

自动化测试的定位及一些思考

大家对自动化的理解&#xff0c;首先是想到Web UI自动化&#xff0c;这就为什么我一说自动化&#xff0c;公司一般就会有很多人反对&#xff0c;因为自动化的成本实在太高了&#xff0c;其实自动化是分为三个层面的&#xff08;UI层自动化、接口自动化、单元测试&#xff09;&a…

井字棋--课后程序(Python程序开发案例教程-黑马程序员编著-第7章-课后作业)

实例2&#xff1a;井字棋 井字棋是一种在3 * 3格子上进行的连珠游戏&#xff0c;又称井字游戏。井字棋的游戏有两名玩家&#xff0c;其中一个玩家画圈&#xff0c;另一个玩家画叉&#xff0c;轮流在3 * 3格子上画上自己的符号&#xff0c;最先在横向、纵向、或斜线方向连成一条…

【Leetcode】【简单】35. 搜索插入位置

给定一个排序数组和一个目标值&#xff0c;在数组中找到目标值&#xff0c;并返回其索引。如果目标值不存在于数组中&#xff0c;返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 示例 1: 输入: nums [1,3,5,6], target 5 输出: 2 示例 2: 输入:…

MSP430F5529单片机入门学习笔记1

本笔记整理自B站教程MSP430F5529单片机学习视频汇总基于库函数的开发—GPIO库函数右边部分写错了&#xff0c;看的时候注意基于库函数的开发—GPIO实践操作LED交替闪烁#include <msp430.h> /** EXP-GPIO-01.C** Created on: 2023年3月10日* Author: ASUS*/#include…

webRtc概念

webRtc概念 以下的文档整理来自此链接 文档整理了一系列实现web通用接口的ECMAScript APIs &#xff0c;这些接口是为了支持浏览器或者一些其他实现了实时交换协议的设备进行媒体信息和程序数据交换。 1、实现点对点通信的规范&#xff1a; NAT穿透实现与远端节点链接比如&a…

WebRTC开源库内部调用abort函数引发程序发生闪退问题的排查

目录 1、初始问题描述 2、使用Process Explorer工具查看到处理音视频业务的rtcmpdll.dll模块没有加载起来 3、使用Dependency Walker工具查看到rtcmpdll.dll依赖的库有问题 4、更新库之后Debug程序启动时就发生异常&#xff0c;程序闪退 5、VS调试时看不到有效的函数调用堆…

hashmap存储方式 hash碰撞及其解决方式

1.Map的存储特点 在Map这个结构中&#xff0c;数据是以键值对&#xff08;key-value&#xff09;的形式进行存储的&#xff0c;每一个存储进map的数据都是一一对应的。 创建一个Map结构可以使用new HashMap()以及new TreeMap()两种方式&#xff0c;两者之间的区别是&#xff1a…

TVS和稳压管的相同点和不同点

大家好,我是记得诚。 文章目录 介绍相同点不同点介绍 TVS和稳压管都是电路中很常用的电子元器件,都是二极管的一个种类。 TVS二极管全称是Transient voltage suppression diode,也叫瞬态电压抑制二极管。 稳压二极管英文名字Zener diode,又叫齐纳二极管。 关于稳压二极…