目录
1、对请求的测试前置、后置处理
2、在web界面添加新内容
3、监听测试的失败率或阀值
4、汇总总结
更多干货
请求有一个上下文参数,通过数据有关的请求(之类的用户名,标签等)。它可以通过覆盖 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"])
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_page
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)
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"])
完整版文档下载方式:
这些资料,对于从事【软件测试】等相关工作的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴我走过了最艰难的路程,希望也能帮助到你!以上均可以分享。
在评论区和我互动交流或者私❤我【软件测试学习】领取即可,拿走不谢。
如果我的博客对你有帮助、如果你喜欢我的博客内容,请 “点赞” “✍️评论” “收藏” 一键三连哦!