性能测试自定义hook(钩子)-通篇讲解 Locust 性能测试

关于自定义钩子 —小试牛刀

Locust 事件钩子(Event Hooks)总结

Locust 提供了许多事件钩子,允许你在测试运行时扩展和自定义功能。以下是一些主要的事件钩子及其使用场景和示例:

1. 请求完成事件(Request Completed Event)

使用场景:当每个请求完成后,你可能希望记录请求的结果,或在请求失败时执行一些操作。

示例

from locust import events

@events.request.add_listener
def my_request_handler(request_type, name, response_time, response_length, response, context, exception, start_time, url, **kwargs):
    if exception:
        print(f"Request to {name} failed with exception {exception}")
    else:
        print(f"Successfully made a request to: {name}")
        print(f"The response was {response.text}")

解释:在这个示例中,我们为 request 事件添加了一个监听器,用于在请求完成后输出信息。如果请求出现异常,打印异常信息;否则,打印请求成功的信息和响应内容。

2. 测试开始和结束事件(Test Start and Stop Events)

使用场景:在分布式模式下,可能需要在测试开始前和结束后执行一些初始化或清理工作。

示例

from locust import events
from locust.runners import MasterRunner

@events.test_start.add_listener
def on_test_start(environment, **kwargs):
    if not isinstance(environment.runner, MasterRunner):
        print("Beginning test setup")
    else:
        print("Started test from Master node")

@events.test_stop.add_listener
def on_test_stop(environment, **kwargs):
    if not isinstance(environment.runner, MasterRunner):
        print("Cleaning up test data")
    else:
        print("Stopped test from Master node")

解释test_starttest_stop 事件用于在测试开始和结束时执行操作。这个示例根据当前节点类型(Master 或 Worker)打印相应的信息,并进行初始化或清理操作。

3. 请求上下文(Request Context)

使用场景:你可能需要在请求中传递额外的数据(如用户名),并在监听器中使用这些数据。

示例

class MyUser(HttpUser):
    @task
    def t(self):
        self.client.post("/login", json={"username": "foo"})
        self.client.get("/other_request", context={"username": "foo"})

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

解释:通过 context 参数可以传递请求数据。在这个示例中,我们在 GET 请求中传递了用户名,并在请求监听器中打印这个用户名。

4. 添加 Web 路由(Adding Web Routes)

使用场景:需要在 Locust 的 Web UI 中添加自定义页面或路由以显示额外的信息。

示例

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"

解释:通过监听 init 事件,我们可以在 Locust 的 Web UI 中添加一个新的路由 /added_page,显示额外的页面内容。

5. 运行后台 Greenlet(Run a Background Greenlet)

使用场景:在测试过程中监控失败率并在超过阈值时停止测试。

示例

import gevent
from locust import events
from locust.runners import STATE_STOPPING, STATE_STOPPED, STATE_CLEANUP, MasterRunner, LocalRunner
import time

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):
    if isinstance(environment.runner, MasterRunner) or isinstance(environment.runner, LocalRunner):
        gevent.spawn(checker, environment)

解释:这个示例中,checker 函数用于定期检查失败率,如果失败率超过 20%,则停止测试。通过在 init 事件中启动 Greenlet 线程来实现这一点。

6. 自定义命令行参数(Custom Command Line Arguments)

使用场景:在测试运行时需要使用自定义命令行参数进行配置。

示例

from locust import HttpUser, events, task

@events.init_command_line_parser.add_listener
def _(parser):
    parser.add_argument("--my-argument", type=str, env_var="LOCUST_MY_ARGUMENT", default="", help="It's working")
    parser.add_argument("--env", choices=["dev", "staging", "prod"], default="dev", help="Environment")

@events.test_start.add_listener
def _(environment, **kw):
    print(f"Custom argument supplied: {environment.parsed_options.my_argument}")

class WebsiteUser(HttpUser):
    @task
    def my_task(self):
        print(f"my_argument={self.environment.parsed_options.my_argument}")

解释:通过 init_command_line_parser 事件添加自定义命令行参数,并在 test_start 事件中打印这些参数的值。这个功能允许用户在运行 Locust 时传递和使用自定义参数。

总结

这些事件钩子可以帮助你在 Locust 测试中进行各种扩展和定制。通过合理利用这些钩子,你可以增强测试的功能性和灵活性,满足各种复杂的测试需求。


自定义命令行参数(Custom Command Line Arguments) —武动乾坤

Locust 允许你在命令行中定义自定义参数,这些参数不仅可以在测试脚本中使用,还可以在 Locust 的 Web UI 中显示和编辑。这可以为用户提供更多的配置选项和灵活性。

使用场景

  • 测试配置:在测试开始时,根据不同的需求或环境配置测试参数。
  • Web UI 集成:在 Locust 的 Web UI 中显示和编辑自定义参数,方便测试人员进行配置调整。

示例代码

以下是如何定义和使用自定义命令行参数,并在 Locust 的 Web UI 中显示这些参数的示例:

from locust import HttpUser, events, task

# 自定义命令行参数
@events.init_command_line_parser.add_listener
def _(parser):
    # 添加一个普通参数
    parser.add_argument("--my-argument", type=str, env_var="LOCUST_MY_ARGUMENT", default="", help="A custom argument")

    # 添加一个具有选项的下拉菜单参数
    parser.add_argument("--env", choices=["dev", "staging", "prod"], default="dev", help="Environment")

    # 添加一个在 Web UI 中不可见的参数
    parser.add_argument("--my-ui-invisible-argument", include_in_web_ui=False, default="I am invisible")

    # 添加一个在 Web UI 中作为密码输入的参数
    parser.add_argument("--my-ui-password-argument", is_secret=True, default="I am a secret")

# 处理测试开始时的参数
@events.test_start.add_listener
def _(environment, **kw):
    print(f"Custom argument supplied: {environment.parsed_options.my_argument}")

class WebsiteUser(HttpUser):
    @task
    def my_task(self):
        # 使用自定义命令行参数
        print(f"my_argument={self.environment.parsed_options.my_argument}")
        print(f"my_ui_invisible_argument={self.environment.parsed_options.my_ui_invisible_argument}")

参数说明

  1. 普通参数

    parser.add_argument("--my-argument", type=str, env_var="LOCUST_MY_ARGUMENT", default="", help="A custom argument")
    
    

    这个参数可以从命令行传递,例如 --my-argument=value,并可以通过环境变量 LOCUST_MY_ARGUMENT 设置。

  2. 选项参数

    parser.add_argument("--env", choices=["dev", "staging", "prod"], default="dev", help="Environment")
    
    

    这个参数会在 Web UI 中显示为一个下拉菜单,用户可以选择不同的环境配置。

  3. 不可见参数

    parser.add_argument("--my-ui-invisible-argument", include_in_web_ui=False, default="I am invisible")
    
    

    这个参数在 Web UI 中不会显示,适用于需要隐藏的配置项。

  4. 密码参数

    parser.add_argument("--my-ui-password-argument", is_secret=True, default="I am a secret")
    
    

    这个参数在 Web UI 中会显示为密码输入框,适用于需要保密的配置项。

在 Web UI 中使用自定义参数

在 Web UI 中,自定义参数将显示在测试设置页面的“设置”部分。你可以根据需要调整这些参数,以便在测试过程中进行不同的配置。参数的显示方式和可编辑性取决于你在定义参数时的配置(例如,是否设置了 include_in_web_ui=Falseis_secret=True)。

通过自定义命令行参数,你可以更灵活地配置和管理 Locust 的测试,满足不同场景下的需求。


测试数据管理(Test Data Management) —完美世界

在 Locust 中,测试数据的管理是一个重要的方面,因为测试通常需要处理大量的数据。这些数据可以通过不同的方式引入到测试中。Locust 通过事件提供了精细的控制,以便在测试执行过程中获取和释放测试数据。

使用场景

  • 动态数据加载:在测试运行时,根据需要动态加载数据,例如从数据库或 API。
  • 数据清理:在测试结束时,释放或清理测试数据,以确保测试环境的干净和一致性。
  • 性能测试:对于需要大量数据的性能测试,动态数据管理可以帮助模拟更真实的负载场景。

示例代码

以下是一个示例,演示了如何在 Locust 中管理测试数据:

import os
import json
import random
from locust import HttpUser, task, events

# 全局变量用于存储测试数据
test_data = []

def load_test_data():
    # 模拟从文件或数据库加载数据
    global test_data
    with open("test_data.json") as f:
        test_data = json.load(f)

def release_test_data():
    global test_data
    test_data = []

@events.test_start.add_listener
def on_test_start(environment, **kwargs):
    load_test_data()

@events.test_stop.add_listener
def on_test_stop(environment, **kwargs):
    release_test_data()

class WebsiteUser(HttpUser):
    @task
    def my_task(self):
        if not test_data:
            print("No test data available")
            return

        # 从测试数据中随机选择一项
        data = random.choice(test_data)

        # 使用测试数据进行请求
        self.client.post("/api/endpoint", json=data)

示例说明

  1. 数据加载

    def load_test_data():
        with open("test_data.json") as f:
            global test_data
            test_data = json.load(f)
    
    

    on_test_start 事件中调用 load_test_data 函数,从文件或数据库中加载测试数据。这是在测试开始时执行的操作。

  2. 数据释放

    def release_test_data():
        global test_data
        test_data = []
    
    

    on_test_stop 事件中调用 release_test_data 函数,释放测试数据,以便测试结束后清理数据。

  3. 使用数据

    class WebsiteUser(HttpUser):
        @task
        def my_task(self):
            if not test_data:
                print("No test data available")
                return
    
            data = random.choice(test_data)
            self.client.post("/api/endpoint", json=data)
    
    

    WebsiteUser 类的 my_task 方法中,使用加载的测试数据进行 HTTP 请求。如果没有数据可用,任务将不会执行。

关键点

  • 数据加载和释放:通过 events.test_startevents.test_stop 事件管理数据的加载和释放,确保测试前后数据的正确性。
  • 数据使用:在任务中使用测试数据,以便在负载测试中模拟真实的场景。

通过以上方法,你可以有效地管理 Locust 中的测试数据,实现更灵活和高效的测试策略。

  • 13
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Wade_Crab

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

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

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

打赏作者

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

抵扣说明:

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

余额充值