Locust性能测试框架

一、Locust介绍

1、Locust简介

Locust(蝗虫)是一个开源的性能测试工具,主要思想就是模拟一群用户访问你的系统

2、特点

(1)在代码中定义用户行为

不需要安装笨重的软件,只是简单的Python代码

(2)分布式和可扩展

Locust支持在多台机器上的运行负载测试,因此可用于模拟数百万用户的请求

(3)经过验证和战斗测试

Locust被用于许多真实的项目中

(4)Locust有一个整洁的HTML+JS的用户界面,实时显示相关测试细节

由于用户界面是基于网络的,它是跨平台的和容易扩展

二、Locust技术架构

安装命令:

pip install locust

安装成功验证:

locust --version # 查看安装的版本 locust -h # 查看使用帮助

注意:python的版本最好在3.7以上

架构组成:

1、Python编写的测试用例方案

2、使用request发送HTTP请求

3、使用协程,低成本的实现更多并发

4、支持分布式

5、使用Flask提供WebIUI

6、有第三方的插件,可以进行扩展

三、locust测试用例的写法

def test_login_smalleel():
    paramsPro = {"username": config.get_user_info("usernamePro"),
                 "password": login_md5(config.get_user_info("usernamePro"), config.get_user_info("passwordPro"))}
    url = ApiUtil(1, "ApiCommon").get_url("LOGIN")
    responsePro = requests.post(url=url, data=paramsPro).json()
    assert responsePro["code"] == 200

将其转为locust的性能测用例,经过几个步骤:

1、创建locust.HttpUser子类

2、为用例加上@locust.task

3、使用self.client发送请求

4、指定wait_time属性

import locust
from common.util.apiUtil.apiUtil import ApiUtil
from common.util.configUtil.configUtil import ConfigUtil
from common.util.md5Util.stringTomd5 import login_md5
from common.util.requestUtil.requestUtil import RequestsUtil

requestUtil = RequestsUtil()
config = ConfigUtil()


class MyUser(locust.HttpUser):  # 1、创建locust.HttpUser子类
    wait_time = locust.between(1, 2)  # 2、每个tast间隔1~2s

    @locust.task
    def test_login_smalleel(self):
        paramsPro = {"username": config.get_user_info("usernamePro"),
                     "password": login_md5(config.get_user_info("usernamePro"), config.get_user_info("passwordPro"))}
        url = ApiUtil(1, "ApiCommon").get_url("LOGIN")
        responsePro = self.client.post(url=url, data=paramsPro).json()
        print(responsePro)
        assert responsePro["code"] == 200


if __name__ == '__main__':
    my = MyUser()
    my.test_login_smalleel()

四、Locust执行多任务模板

 
import random
from locust import TaskSequence, HttpLocust, task, seq_task, between


# 定义一个任务类,这个类名称自己随便定义,类继承TaskSequence 或 TaskSet类,所以要从locust中,引入TaskeSequence或TaskSet
# 当类里面的任务请求有先后顺序时,继承TaskSequence类, 没有先后顺序,可以使用继承TaskSet类
class MyTaskCase(TaskSequence):
    # 初始化方法,相当于 setup
    def on_start(self):
        pass

    # @task python中的装饰器,告诉下面的方法是一个任务,任务就可以是一个接口请求,
    # 这个装饰器和下面的方法被复制多次,改动一下,就能写出多个接口
    # 装饰器后面带上(数字)代表在所有任务中,执行比例
    # 要用这个装饰器,需要头部引入 从locust中,引入 task
    @task
    @seq_task(1)  # 装饰器,定义有执行顺序的任务,扩展中的数字,从小到大,代表先后执行顺序
    def regist_(self):  
        url = '/erp/regist'  
        self.headers = {"Content-Type": "application/json"}  
        self.user = "locust_" + str(random.randint(10000, 100000))
        self.pwd = '1234567890'
        data = {"name": self.user, "pwd": self.pwd}  # post请求的 请求体
        # 使用self.client发起请求,请求的方法根据接口实际选,
        # catch_response 值为True 允许为失败 , name 设置任务标签名称   -----可选参数
        rsp = self.client.post(url, json=data, headers=self.headers, catch_response=True, name='api_regist')
        if rsp.status_code == 200:
            rsp.success()
        else:
            rsp.failure('regist_ 接口失败!')

    @task  # 装饰器,说明下面是一个任务
    @seq_task(2)  # 顺序任务装饰器,说明下面的任务,第二个执行
    def login_(self):
        url = '/erp/loginIn' 
        data = {"name": self.user, "pwd": self.pwd}
        rsp = self.client.post(url, json=data, headers=self.headers,
                               catch_response=True)  # 使用self.client发起请求,请求的方法 选择post
        self.token = rsp.json()['token']    
        if rsp.status_code == 200 and rsp.json()['code'] == "200":
            rsp.success()
        else:
            rsp.failure('login_ 接口失败!')

    @task  # 装饰器,说明下面是一个任务
    @seq_task(3)  # 顺序任务装饰器,说明下面的任务,第三个执行
    def getuser_(self):
        url = '/erp/user'  
        headers = {"Token": self.token}  
        rsp = self.client.get(url, headers=headers, catch_response=True)  # 使用self.client发起请求,请求的方法 选择 get
        if rsp.status_code == 200:
            rsp.success()
        else:
            rsp.failure('getuser_ 接口失败!')

    # 结束方法, 相当于teardown
    def on_stop(self):
        pass


# 定义一个运行类 继承HttpLocust类, 所以要从locust中引入 HttpLocust类
class UserRun(HttpLocust):
    task_set = MyTaskCase  # 定义固定的 task_set  指定前面的任务类名称
    wait_time = between(0.1, 3)  # 设置运行过程中间隔时间 需要从locust中 引入 between


'''
运行:
    在终端中输入:locust -f 被执行的locust文件.py --host=http://被测服务器域名或ip端口地址
    也可以不指定host
命令执行成功,会提示服务端口,如:*:8089
此时,则可通过浏览器访问机器ip:8089,看到任务测试页面
'''

五、Locust执行压测

4.1 通过WebUI执行

优点:简单+绘制图表(直观)

py文件没有问题的话,将可以通过浏览器访问 http://localhost:8089 访问locust服务.

locust -f .\z_demo\demo1.py
启动:http://localhost:8089/

第1个"Number of total users to simulate" 填写的是 总共将运行的用户数;

第2个 "Hatch rate"每秒加载的用户数;

第3个 "Host",被测接口的域名或ip端口地址(带http://),

Start swarming , 启动

如图

 

 

 

4.2 通过命令行执行

  1. 指定运行时的ip和端口
 locust -f 被执行的文件.py  --web-host 127.0.0.1 -P 8389

此时,浏览器访问 http://localhost:8089 时,页面中,已经自动带入了 Host值

  1. 无图形界面(无头模式)模式

无头模式,即无图形界面模式,不能通过浏览器访问页面来设置性能测试场景,只能通过命令中带参数来设置。参考命令如下:

locust -f 被执行的文件.py --no-web -c 30 -r 2 -t 2m --host=http://ip:8080 --csv=结果报告文件前缀
# --no-web 指名用无图形界面模式
# -c 指定运行的最大用户数,对应图形界面中的 Number of total users to simulate
# -r 指定每秒生成用户数,对应图形界面中的 Hatch rate
# -t 指定总共运行时长,因在无图形界面中,没有停止按钮,需要有这个参数才能到时间就停止,不然会一直运行下去,直到终端ctrl+c强行停止
# --host 指定被测服务器域名或ip端口地址
# --csv 指定输出结果到csv文件的前缀

这样,就会按照设置的参数,运行,到达运行时长自动停止,同时把测试结果写到配置的文件前缀的 '_stats.csv' 和 '_stats_history.csv' 文件中.

  1. 分布式运行

locust 除了上面两种常用的模式外,还有一种叫分布式,就是用主控机器,控制助攻机,一起执行测试。

Ⅰ.主控机器master和助攻机器slave,同一台机器

启动主控进程,在终端中执行:

locust -f 被执行的文件.py --master

启动助攻进程,在终端中执行:

locust -f 被执行的文件.py --slave
  • 注意:

  • Ⅰ 助攻进程可以启动多个,在多个终端中执行启动助攻进程,就能启动多个。

  • Ⅱ 主控机master和助攻机slave,启动顺序没有要求

  • Ⅲ 启动主控机master后,检测到有助攻机进程,就会显示 'Client reported as ready. Currently N** clients ready to swarm.' N指代数量

  • Ⅳ 分布式支持图形界面、无图形界面,相比而言,图形界面用的较多,因为能轻松控制所有助攻机slave一起执行;分布式执行无图像界面命令,建议先启动助攻机slave,然后再在启动主控机master时,指定命令,不然,助攻机器将可能不同时执行。

  • Ⅴ 分布式在执行时,设置的total users、Hatch rate,将平均分配到各个助攻机slave中执行。

  • Ⅵ 建议一台机器slave个数,不要超过cpu核数数量。

Ⅱ. 主控机器master和助攻机器slave,不是同一台机器

启动主控机器主进程master,在终端中执行:

locust -f 被执行的文件.py --master

locust -f 被执行的文件.py --master

locust -f 被执行的文件.py --slave --master-host=主控机器ip --master-port=5557
  • 注意:

  • 启动助攻机器进程时,--master-host指定主控机器master的ip地址,如果不带master-port则用默认的5557端口,如果主控机器指定了端口,则这个要对应修改

  • 其他,与在同一台机器上一样

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

QIks

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值