locustfile是什么?

locustfile是Locust性能测试工具的用户脚本,描述了单个用户的行为。

locustfile是个普通的Python模块,如果写作locustfile.py,那么路径切换到文件所在目录,直接执行命令就能运行:

$ locust

如果换个名字,那么只能通过-f参数指定文件名运行:

$ locust -f locust_files/my_locust_file.py

与一般Python模块不同的是:locustfile必须至少定义一个类,且继承自User类。

User类

User类表示性能测试的模拟用户,Locust会在运行时创建User类的实例

wait_time属性

设置等待时间,默认值不等待,立即执行。

Locust支持4种方式设置wait_time属性

为了便于理解实际意义,我把源码贴在了下面。

  • constant函数,常量,任务执行完毕等待X秒开始下一任务。

    def constant(wait_time):
    """
    Returns a function that just returns the number specified by the wait_time argument Example:: class MyUser(User):
    wait_time = constant(3)
    """
    return lambda instance: wait_time
  • between函数,区间随机值,任务执行完毕等待X-Y秒(中间随机取值)开始下一任务。

    def between(min_wait, max_wait):
    """
    Returns a function that will return a random number between min_wait and max_wait. Example:: class MyUser(User):
    # wait between 3.0 and 10.5 seconds after each task
    wait_time = between(3.0, 10.5)
    """
    return lambda instance: min_wait + random.random() * (max_wait - min_wait)
  • constant_pacing函数,自适应,若任务耗时超过该时间,则任务结束后立即执行下一任务;若任务耗时不超过该时间,则等待达到该时间后执行下一任务。

    def constant_pacing(wait_time):
    """
    Returns a function that will track the run time of the tasks, and for each time it's
    called it will return a wait time that will try to make the total time between task
    execution equal to the time specified by the wait_time argument. In the following example the task will always be executed once every second, no matter
    the task execution time:: class MyUser(User):
    wait_time = constant_pacing(1)
    @task
    def my_task(self):
    time.sleep(random.random()) If a task execution exceeds the specified wait_time, the wait will be 0 before starting
    the next task.
    """ def wait_time_func(self):
    if not hasattr(self, "_cp_last_run"):
    self._cp_last_wait_time = wait_time
    self._cp_last_run = time()
    return wait_time
    else:
    run_time = time() - self._cp_last_run - self._cp_last_wait_time
    self._cp_last_wait_time = max(0, wait_time - run_time)
    self._cp_last_run = time()
    return self._cp_last_wait_time return wait_time_func
  • 自定义wait_time方法,比如每次等待时间1秒2秒3秒递增:

    class MyUser(User):
    last_wait_time = 0 def wait_time(self):
    self.last_wait_time += 1
    return self.last_wait_time ...

weight属性

设置创建类实例的权重,默认每个类创建相同数量的实例。

locustfile中可以有多个继承了User类的类

命令行可以指定运行哪些类:

$ locust -f locust_file.py WebUser MobileUser

通过weight属性可以让类更大概率创建实例,比如:

class WebUser(User):
weight = 3
... class MobileUser(User):
weight = 1
...

WebUser类比MobileUser类多三倍概率创建实例。

host属性

设置URL前缀。

一般是在Locust的Web UI或者命令行,通过--host指定URL前缀。如果没有通过--host指定,并且类中设置了host属性,那么类的host属性才会生效。

environment属性

对用户运行环境的引用。

比如在task方法中通过environment属性终止运行:

self.environment.runner.quit()

注意,单机会终止所有运行,分布式只会终止单个worker节点。

on_start和on_stop方法

测试前初始化和测试后清理。

HttpUser类

开篇文章的示例脚本,没有继承User类,而是继承了它的子类HttpUser:

它比User类更常用,因为它添加了一个client属性,用来发送HTTP请求

client属性/HttpSession

HttpUser类的client属性是HttpSession类的一个实例:

HttpSession是requests.Session的子类,requests就是常用来做接口测试的那个requests库:

HttpSession没有对requests.Session做什么改动,主要是传递请求结果给Locust,比如success/fail,response time,response length,name。

示例:

response = self.client.post("/login", {"username":"testuser", "password":"secret"})
print("Response status code:", response.status_code)
print("Response text:", response.text)
response = self.client.get("/my-profile")

由于requests.Session会暂存cookie,所以示例中登录/login请求后可以继续请求/my-profile

断言响应结果

可以使用with语句和catch_response参数对响应结果进行断言:

with self.client.get("/", catch_response=True) as response:
if response.text == "Success":
response.success()
elif response.text != "Success":
response.failure("Got wrong response")
elif response.elapsed.total_seconds() > 0.5:
response.failure("Request took too long")

或者直接抛出异常:

from locust.exception import RescheduleTask
...
with self.client.get("/does_not_exist/", catch_response=True) as response:
if response.status_code == 404:
raise RescheduleTask()

name参数

name参数用于把不同api按同一分组进行统计,比如:

for i in range(10):
self.client.get("/blog?id=%i" % i, name="/blog?id=[id]")

会按/blog/?id=[id]统计1条数据,而不是分成10条数据。

HTTP代理

Locust默认设置了requests.Session的trust_env为False,不查找代理,以提高运行性能。如果需要可以设置locust_instance.client.trust_env为True。

示例代码

请求REST API并断言:

from json import JSONDecodeError
...
with self.client.post("/", json={"foo": 42, "bar": None}, catch_response=True) as response:
try:
if response.json()["greeting"] != "hello":
response.failure("Did not get expected value in greeting")
except JSONDecodeError:
response.failure("Response could not be decoded as JSON")
except KeyError:
response.failure("Response did not contain expected key 'greeting'")

小结

locustfile是个普通Python模块,必须继承User类或其子类HttpUser等。本文对User类和HttpUser类的属性和方法进行了介绍,使用它们可以编写性能测试的用户脚本。locustfile还有另外一个重要组成元素,@task

参考资料:

https://docs.locust.io/en/stable/writing-a-locustfile.html

https://blog.csdn.net/Orangesir/article/details/114914969

locustfile中的User类和HttpUser类的更多相关文章

  1. JS面向对象(1) -- 简介,入门,系统常用类,自定义类,constructor,typeof,instanceof,对象在内存中的表现形式

    相关链接: JS面向对象(1) -- 简介,入门,系统常用类,自定义类,constructor,typeof,instanceof,对象在内存中的表现形式 JS面向对象(2) -- this的使用,对 ...

  2. java中的 FileWriter类 和 FileReader类的一些基本用法

    1,FileWriter类(字符输出流类) |--用来写入字符文件的便捷类.此类的构造方法假定默认字符编码和默认字节缓冲区大小都是可接受的.要自己指定这些值,可以先在 FileOutputStream ...

  3. 22.编写一个类A,该类创建的对象可以调用方法showA输出小写的英文字母表。然后再编写一个A类的子类B,子类B创建的对象不仅可以调用方法showA输出小写的英文字母表,而且可以调用子类新增的方法showB输出大写的英文字母表。最后编写主类C,在主类的main方法 中测试类A与类B。

    22.编写一个类A,该类创建的对象可以调用方法showA输出小写的英文字母表.然后再编写一个A类的子类B,子类B创建的对象不仅可以调用方法showA输出小写的英文字母表,而且可以调用子类新增的方法sh ...

  4. Nutz中那些好用的工具类

    Nutz 是国产的精品开源框架,它全无依赖,只以1兆多的身材,就可以实现SSH全部功能的90%以上.内容主要涵盖了:Ioc.Aop.MVC.Dao.Json等WEB开发的方方面面.  它不仅轻巧,而且 ...

  5. 【转载】C++中的基类与派生类

    转自:http://www.cnblogs.com/sujz/articles/2044365.html 派生类的继承方式总结: 继承方式 说明 public 基类的public和protected的 ...

  6. 在lua脚本中使用我们自定义的精灵类

    首先创建cocos2dx-lua项目,然后在项目中添加我们的自定义精灵类:这里Himi类名为:HSprite // // HSprite.h // cocos2dx_lua_tests_by_Himi ...

  7. 【JAVA中String、StringBuffer、StringBuilder类的使用】

    一.String类概述 1.String对象一旦创建就不能改变. 2.字符串常量池. 字符串常量池的特点:池中有则直接使用,池中没有则创建新的字符串常量. 例1: public class Strin ...

  8. 理解是最好的记忆方法 之 CSS中a链接的④个伪类为何有顺序

    理解是最好的记忆方法 之 CSS中a链接的④个伪类为何有顺序 在CSS中,a标签有4种伪类,分别为: a:link, a:visited, a:hover, a:active 对其稍有了解的前端er都 ...

  9. (转) C++中基类和派生类之间的同名函数的重载问题

    下面有关派生类与基类中存在同名函数 fn: class A { public: void fn() {} void fn(int a) {} }; class B : public A { publi ...

随机推荐

  1. ACM常用的C++ && STL

    内容 c++输入输出 c++ string vector:不定长数组 map:映射 queue:队列 sort:排序 priority_queue:优先队列 c++输入输出 1 #include &l ...

  2. 如何使用jQuery $.post() 方法实现前后台数据传递

    基础方法为 $.post(URL,data,callback); 参数介绍: 1.URL 参数规定您希望请求的 URL. 2.data 参数规定连同请求发送的数据. 3.callback 参数是请求成 ...

  3. Linux wget 使用笔记

    wget 是 Linux 上最常用的文件下载工具,简单实用.记录一下一些常用的操作备查. 最常用最简单的操作就是直接使用一个 URL 下载 下载互联网上指定的文件 wget https://gemme ...

  4. WebGPU[1] 三角形

    代码见: https://github.com/onsummer/my-dev-notes/tree/master/webgpu-Notes/01-triangle 如果本篇的代码不能跑了,请联系我或 ...

  5. [题解] T'ill It's Over

    前言 线段树+网络最大流的建模题. 博客园食用更佳 题目大意 最初时有 \(n\) 个 \(1\) .给定 \(op\) . \(l\) ,其中, \(l\) 为操作次数上限.你有四个操作: 若 \( ...

  6. Vscode部分快捷键 Ps的简单使用 less中的除法问题 H5 四种布局

    vscode 部分快捷键 ctrl+/ 注释ctrl+回车 光标下移alt+shift+上下箭头 将本行代码向上或向下复制ul>li 自动写alt ,鼠标一直点,就会有很多光标,可以一起写ctr ...

  7. SQLserver数据库安装教程

    大家好,这期给大家带来一期SQL server的安装教程 下载SQL Server 2019 Developer 官方网址: https://www.microsoft.com/zh-cn/sql-s ...

  8. python中的数据结构-链表

    一.什么是链表 链表是由一系列节点构成,每个节点由一个值域和指针域构成,值域中存储着用户数据,指针域中存储这指向下一个节点的指针.根据结构的不同,链表可以分为单向链表.单向循环链表.双向链表.双向循环 ...

  9. pwnable.tw 3x17

    3x17 文章主要是参考了https://xuanxuanblingbling.github.io/ctf/pwn/2019/09/06/317/ 首先我们检查一下开启的保护 运行一下,先让输入add ...

  10. ECDSA密钥对生成以及在Token中的应用

    1 概述 本文主要讲述了如何利用Openssl生成ECDSA密钥对,并利用Auth0库进行Token生成及验证的过程. 2 ECDSA 2.1 简介 ECC(Elliptic Curve Crypto ...