locust学习教程(8) - event 事件

news2024/12/23 0:30:22

目录

1、对请求的测试前置、后置处理

2、在web界面添加新内容

3、监听测试的失败率或阀值

4、汇总总结

🎁更多干货


1、对请求的测试前置、后置处理

  请求有一个上下文参数,通过数据有关的请求(之类的用户名,标签等)。它可以通过覆盖 User.context() 方法直接在对请求方法的调用中或在用户级别设置。

class MyUser(HttpUser):
    def context(self):
        return {"username": self.username}

    @task
    def t(self):
        self.username = "foo"
        self.client.post("/login", json={"username": self.username})

    @events.request.add_listener
    def on_request(context, **kwargs):
        print(context["username"])

2、在web界面添加新内容

  Locust 使用 Flask 为 Web UI 提供服务,因此很容易将 Web 端点添加到 Web UI。通过侦听init事件,我们可以检索对 Flask 应用程序实例的引用,并使用它来设置新路由:

from locust import events

@events.init.add_listener
def on_locust_init(environment, **kw):
    @environment.web_ui.app.route("/added_page")
    def my_added_page():
        return "Another page"

访问网址:http://localhost:8089/ added_pa​​ge

3、监听测试的失败率或阀值

from locust import events
from locust.runners import STATE_STOPPING, STATE_STOPPED, STATE_CLEANUP, WorkerRunner

def checker(environment):
    while not environment.runner.state in [STATE_STOPPING, STATE_STOPPED, STATE_CLEANUP]:
        time.sleep(1)
        if environment.runner.stats.total.fail_ratio > 0.2:
            print(f"fail ratio was {environment.runner.stats.total.fail_ratio}, quitting")
            environment.runner.quit()
            return


@events.init.add_listener
def on_locust_init(environment, **_kwargs):
    # only run this on master & standalone
    if not isinstance(environment.runner, WorkerRunner):
        gevent.spawn(checker, environment)

4、汇总总结

import datetime
import json
import logging
import time
import gevent
import requests
from locust import task, HttpUser, between
from locust import events
from locust.runners import MasterRunner
from locust.runners import STATE_STOPPING, STATE_STOPPED, STATE_CLEANUP, WorkerRunner


# 这里主要是 event hooks 的示例,用于各种测试监听,测试前置、后置、每个任务请求后的处理等等。


def timestring():
    """
    解析locustfile,比其他任何事情都要早
    :return:
    """
    now = datetime.datetime.now()
    return datetime.datetime.strftime(now, "%m:%S.%f")[:-5]


global_test_data = requests.post("https://postman-echo.com/post",
                                 data="global_test_data_" + timestring(),).json()["data"]
test_run_specific_data = None


def checker(environment):
    """
    定义了失败率判断的函数,主要用于 @events.init.add_listener 进行监听
    :param environment:
    :return:
    """
    while not environment.runner.state in [STATE_STOPPING, STATE_STOPPED, STATE_CLEANUP]:
        time.sleep(1)
        if environment.runner.stats.total.fail_ratio > 0.2:
            print(f"fail ratio was {environment.runner.stats.total.fail_ratio}, quitting")
            environment.runner.quit()
            return


@events.init.add_listener
def on_locust_init(environment, **_kwargs):
    """
    监控测试的失败率并在超过某个阈值时(0.2)停止运行
    :param environment:
    :param _kwargs:
    :return:
    """
    # only run this on master & standalone
    if not isinstance(environment.runner, WorkerRunner):
        gevent.spawn(checker, environment)


@events.init.add_listener
def on_locust_init(environment, **kw):
    """
    添加web界面,可以直接访问:http://localhost:8089/added_page,用于自定义拓展web界面
    源码有拓展的示例
    """
    @environment.web_ui.app.route("/added_page")
    def my_added_page():
        return "Another page"


@events.init.add_listener
def _(environment, **_kwargs):
    """
    初始化蝗虫,发生在解析蝗虫文件之后但测试开始之前,比如增加额外的web界面
    """
    print("2. Initializing locust, happens after parsing the locustfile but before test start")


@events.quitting.add_listener
def _(environment, **_kwargs):
    print("locust is shutting down")


@events.quitting.add_listener
def _(environment, **kw):
    """
    如果满足以下任何条件,则将退出代码设置为非零:
    超过 1% 的请求失败
    平均响应时间大于 200 ms
    响应时间的第 95 个百分位数大于 800 毫秒
    """
    if environment.stats.total.fail_ratio > 0.01:
        logging.error("Test failed due to failure ratio > 1%")
        environment.process_exit_code = 1
    elif environment.stats.total.avg_response_time > 200:
        logging.error("Test failed due to average response time ratio > 200 ms")
        environment.process_exit_code = 1
    elif environment.stats.total.get_response_time_percentile(0.95) > 800:
        logging.error("Test failed due to 95th percentile response time > 800 ms")
        environment.process_exit_code = 1
    else:
        environment.process_exit_code = 0


@events.test_start.add_listener
def _(environment, **_kwargs):
    """
    在headless运行中仅发生一次,但在web ui运行中可能发生多次
    在分布式运行中,主机通常不需要任何测试数据
    :param environment:
    :param _kwargs:
    :return:
    """
    global test_run_specific_data
    print("3. Starting test run")
    if not isinstance(environment.runner, MasterRunner):
        test_run_specific_data = requests.post(
            "https://postman-echo.com/post",
            data="test-run-specific_" + timestring(),
        ).json()["data"]


@events.test_start.add_listener
def on_test_start(environment, **kwargs):
    """
    在分布式模式下运行 locust 时,在运行测试之前在工作节点上进行一些设置可能会很有用。
    可以通过检查节点的类型来检查以确保您没有在主节点上运行runner
    :param environment:
    :param kwargs:
    :return:
    """
    if not isinstance(environment.runner, MasterRunner):
        print("Beginning test setup")
    else:
        print("Started test from Master node")


@events.test_stop.add_listener
def _(environment, **_kwargs):
    print("stopping test run")


@events.test_stop.add_listener
def on_test_stop(environment, **kwargs):
    """
    监听测试执行,执行结束后,自动清楚数据
    :param environment:
    :param kwargs:
    :return:
    """
    if not isinstance(environment.runner, MasterRunner):
        print("Cleaning up test data")
    else:
        print("Stopped test from Master node")


@events.request.add_listener
def my_request_handler(request_type, name, response_time, response_length, response,
                       context, exception, start_time, url, **kwargs):
    """
    对所有的类添加监听器:每个类的任务执行完成后,定义了输出响应的相关内容,这个可以放到locufile文件里面
    """
    if exception:
        print(f"Request to {name} failed with exception {exception}")
    else:
        print(f"request_type : {request_type}")
        print(f"response_time : {response_time}")
        print(f"response_length : {response_length}")
        print(f"context : {context}")
        print(f"start_time : {start_time}")
        print(f"url : {url}")
        print(f"Successfully made a request to: {name}")
        print(f"The response : {response.text}")


class UserBehavior1(HttpUser):
    """
    登录
    """
    host = "https://yyy.com"
    wait_time = between(2, 5)  # 每个任务执行后等待2-5秒

    @task  # Locust 创建一个 greenlet(微线程),一个微线程可以跑很多协程
    def test_login(self):
        data = json.dumps({
            "user1": "tfjiao",
        })
        self.username = "xxx"
        headers = {"Content-Type": "application/json"}
        r = self.client.post("/api/login", data=data, headers=headers)

    def context(self):
        """
        :return: context 用于请求的监听,自定义输出内容
        """
        return {"username": self.username}

    # request context
    # 给userbehaver1类设置了请求的监听,触发什么时候,执行什么操作,这里执行打印操作
    @events.request.add_listener
    def on_request(context, **kwargs):
        if context:
            print(context["username"])

🎁更多干货


 

完整版文档下载方式:

这些资料,对于从事【软件测试】等相关工作的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴我走过了最艰难的路程,希望也能帮助到你!以上均可以分享。

在评论区和我互动交流或者私❤我【软件测试学习】领取即可,拿走不谢。


如果我的博客对你有帮助、如果你喜欢我的博客内容,请 “👍点赞” “✍️评论” “💙收藏” 一键三连哦!

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

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

相关文章

Leaflet实现要素点击查询弹窗展示属性

leaflet是一个非常轻量的webgis框架,同时呢代码结构也比较简单。 如果项目上有需求需要大家实现对于个行政区点击查询相关属性并且展示,就像下图这样: 我们可以这样做。首先要清楚leaflet框架的构造,leaflet在加载图层的时候是对图层添加了事件监听的,也就是说用户对于图…

C++基础强化项目-职工管理系统

通过本项目练习c的基础知识 项目界面头文件workermanager.h(管理类)worker.h(职工抽象类)manager.h(经理类)employee.h(普通职工类)boss.h(老板类) 源文件emp…

多传感器时频信号处理:多通道非平稳数据的分析工具(Matlab代码实现)

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…

新浪微博“私信留言收费”:私域引流危险了

我是卢松松,点点上面的头像,欢迎关注我哦! 从今日起很多新浪微博用户发现:微博用私信要收费了,确切的说是对方没有回关或回复你之前,你只能发送一条消息。开通会员后能发送更多留言。如下图所示&#xff1…

卷积计算加速方法--slice卷积

文章目录 1、前言2、分块卷积存在的问题3、分块卷积问题的解决方案--slice卷积4、slice卷积每层所需切分尺寸计算4、结论及加速效果 1、前言 我们在上一篇卷积计算加速方法中讨论过,当卷积的输入太大导致内存不够用时,考虑将一大块卷积分成多个小块分别进…

多快好省!硫元素循环分析内容又升级啦!

元素循环是生物地球化学循环的重要环节,主要涉及碳、氮、磷、硫等元素的循环过程。凌恩生物强势推出基于宏基因组的硫循环研究方案,构建了完整的硫循环循环模式图,对宏基因组数据进行深入挖掘,各部分结果图可直接用于文章发表&…

iOS 开发 | 自定义不规则 label

把我之前发布在简书的博客搬运过来。 目录 场景思路具体实现1. 自定义一个继承自UILabel的IrregularLabel2. 在初始化方法中进行相应初始化和设置3. 在layoutSubviews方法中进行路径的设置 最终效果箭头 label 场景 最近 App 改版,以下是截取的部分 UI 设计图&…

报表测试如何做?软件测试实战,超详细测试点分析(全覆盖)

目录:导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜) 前言 报表测试是一项重…

qt学习 tcp实现 c++

这里写目录标题 qt网络编程qt下的TCP 编程设计ui界面监听关闭和发送调试 查找网络调试助手,用助手当客户端测试 编写的服务端newConnection()newConnection_Slot() Tcp Client界面设计代码部分1关闭客户端发送客户端整体疑惑 https://www.bilibili.com/video/BV1tp4…

Android CMake

首先了解几个名词 NDK The Android Native Development Kit The Android NDK is a toolset that lets you implement parts of your app in native code, using languages such as C and C. For certain types of apps, this can help you reuse code libraries written in t…

虚实相生的元宇宙,不仅仅是在做虚拟社交?

互联网迭代速度已经超出了人们的想象,从Web1.0到Web 2.0,以及紧随其后的 Web 3.0。 不管我们愿不愿意承认,元宇宙的时代已经真真切切地到来了,它的兴起也是社会发展到一定阶段的必然现象。随着时代的发展,如今创作者的…

OpenWrt uci网络配置详解

配置文件 OpenWrt所有配置保存在/etc/config目录,以下为主要的网络配置文件 网络接口配置 /etc/config/network网络服务配置 /etc/config/dhcp防火墙配置 /etc/config/firewall 网络接口 OpenWrt网络接口一般包含lan口和wan口,但如果是X86等设备&…

十五.EtherCAT开发之对象字典的映射原理

十五.EtherCAT开发之对象字典的映射原理 15.1 协议栈文件含义 仔细阅读四个代码文件 l 文件el9800appl.c:主函数,数据收发函数所在 l 文件el9800appl.h:对象字典定义所在,包含对象字典的类型、权限、长度、映射关系、链接变量…

Restful风格笔记

Restful风格知识点 RestController注解 在类上添加RestController可以默认类中的所有方法都带有ResponseBody注解,可以省去一个个添加的麻烦。 RestController RequestMapping("/restful") //CrossOrigin(origins {"http://localhost:8080"…

第六节 元组、字典

文章目录 掌握知识点1. 元组1.1 元组概述1.2 语法格式1.3 元组场景使用 2. 字典2.1 概述2.2 字典的语法结构与注意2.3 字典CURD2.3.1 字典获取2.3.2 字典添加和修改2.3.3 字典删除2.3.4 字典遍历 2.4 enumerate 函数2.5 扩展练习2.5.1 判断是否能全部购买2.5.2 学生信息的排序2…

图像中的脸部、四肢问题及其解决方法

在SD绘图的时候经常会出现多个头部、多个身体部位或者多个手指的问题这里介绍一些通用的简单的解决办法。 文章目录 多个人物或者部位没有全身出境使用纵向尺寸脸部乱码和眼睛问题人物手指乱问题 多个人物或者部位 绘图基本信息 正面词 <lora:DynastyWarriors_wu_cloth:1…

若依框架学习

1.若依&#xff08;前后端分离版&#xff09; 1.1什么是若依 开源项目&#xff0c;学习开源项目的目的&#xff1a; 1.用别人的&#xff0c;减少自己的工作量 2.学习他的底层编程思想&#xff0c;设计思路&#xff0c;提高自己的编程能力 官网&#xff1a;www.ruoyi.vip …

“AI+RPA+数据+机器人”:深入解析“数字员工”的内涵和价值

世界正进入数字经济快速发展的时期。 2021年12月&#xff0c;中央网络安全和信息化委员会印发《“十四五”国家信息化规划》&#xff0c;提出加快建设数字中国&#xff0c;大力发展数字经济的总体目标&#xff1b;2022年1月&#xff0c;央行印发《金融科技发展规划&#xff08…

第十章 番外篇:DDP

参考教程&#xff1a; what is DDP pytorch distributed overview 文章目录 DDP介绍什么是DDPDistributedSampler()DistributedDataParallel() 使用DDP代码示例multiprocessing.spawn()save and load checkpoints DDP介绍 什么是DDP DDP的全称是DistributedDataParallel&…

Qt控件学习

目录 QPushButton QToolButton QRadioButton QCheckBox QPushButton MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow) {ui->setupUi(this);ui->n1->setText("我的世界");ui->n1->setIcon(QIcon(":/111…