杰瑞科技汇

loadrunner 调用python

  • 处理复杂的 JSON/XML 数据
  • 进行加密/解密操作
  • 调用外部 API 或服务
  • 执行文件操作(如读取、解析、写入)
  • 进行数学计算或科学计算

下面我将详细介绍几种主流的实现方法,从最推荐到最不推荐的顺序进行说明。

loadrunner 调用python-图1
(图片来源网络,侵删)

使用 lr_system_call (最推荐、最简单)

这是最直接、最简单的方法,适用于大多数场景,它通过 LoadRunner 的内置函数调用操作系统的命令行。

工作原理

LoadRunner 执行一个系统命令(python script.py),并将脚本的输出结果捕获到一个变量中。

步骤示例

  1. 准备 Python 脚本 创建一个名为 calculate_sum.py 的 Python 文件,内容如下,这个脚本接收两个命令行参数,计算它们的和,并打印结果。

    # calculate_sum.py
    import sys
    if len(sys.argv) != 3:
        print("Usage: python calculate_sum.py <num1> <num2>")
        sys.exit(1)
    try:
        num1 = int(sys.argv[1])
        num2 = int(sys.argv[2])
        sum_result = num1 + num2
        # 将结果打印到标准输出,这样 lr_system_call 可以捕获到
        print(sum_result)
    except ValueError:
        print("Error: Please provide valid integers.")
        sys.exit(1)
  2. 在 LoadRunner 脚本中调用 在你的 LoadRunner C 脚本(.c 文件)中,使用 lr_system_call 函数。

    loadrunner 调用python-图2
    (图片来源网络,侵删)
    #include "lrunet.h"
    Action()
    {
        int a = 10;
        int b = 20;
        char command[256];
        char output_buffer[256];
        // 构建命令字符串
        // 注意:Python 脚本的路径和参数需要正确填写
        sprintf(command, "python C:/path/to/your/calculate_sum.py %d %d", a, b);
        lr_output_message("Executing command: %s", command);
        // 执行系统命令,并捕获输出
        int return_code = lr_system_call(command, output_buffer, sizeof(output_buffer));
        if (return_code == 0) {
            lr_output_message("Python script executed successfully.");
            lr_output_message("The captured output is: %s", output_buffer);
            // 你可以将捕获到的字符串转换为数字,用于后续事务
            int sum = atoi(output_buffer);
            lr_save_string(output_buffer, "python_sum_result"); // 保存到参数中
            lr_output_message("Sum saved as parameter: %s", lr_eval_string("{python_sum_result}"));
        } else {
            lr_error_message("Failed to execute Python script. Return code: %d", return_code);
            lr_error_message("Output: %s", output_buffer);
        }
        return 0;
    }
  3. 注意事项

    • Python 环境:确保 LoadRunner 运行的机器上已经安装了 Python,python 命令可以在系统的 PATH 环境变量中被找到,如果不是,你需要使用 Python 的完整路径,C:\Python39\python.exe
    • 路径问题:脚本路径和文件路径最好使用绝对路径,以避免因工作目录不同而找不到文件。
    • 性能:每次调用 lr_system_call 都会启动一个新的 Python 解释器进程,有一定的开销,对于极高频率的调用(例如在循环中),这可能会成为性能瓶颈。
    • 返回值lr_system_call 的第一个返回值是命令的退出码(0 表示成功),第二个参数是你提供的缓冲区,用于存放命令的标准输出。

使用 lr_eval_string 与命令行结合 (适用于单行脚本)

如果你的 Python 代码非常简单,只是一行,可以直接嵌入到 LoadRunner 的 lr_eval_string 中。

步骤示例

#include "lrunet.h"
Action()
{
    // 使用 -c "..." 选项直接执行 Python 代码
    // 注意:代码中的引号需要进行转义
    char python_command[] = "python -c \"import sys; print(sys.version.split()[0])\"";
    char version[256];
    lr_system_call(python_command, version, sizeof(version));
    lr_output_message("Python version captured: %s", version);
    return 0;
}

优点:无需创建外部文件。 缺点:只适合极简场景,复杂代码难以维护,引号转义容易出错。


通过 Web 服务/Socket 通信 (最灵活、性能最高)

这是最强大、最灵活的方法,尤其适合复杂场景和性能要求高的测试。

loadrunner 调用python-图3
(图片来源网络,侵删)

工作原理

  1. 启动一个独立的 Python Web 服务(例如使用 Flask 或 FastAPI),这个服务暴露出 API 接口。
  2. LoadRunner 脚本不再直接调用 Python,而是像普通的 HTTP 请求一样,调用这个 Web 服务的接口。
  3. Python 服务处理请求,并返回结果。

步骤示例

  1. 创建 Python Web 服务 安装 Flask: pip install Flask 创建一个 api_server.py 文件。

    # api_server.py
    from flask import Flask, request, jsonify
    import sys
    app = Flask(__name__)
    @app.route('/calculate', methods=['GET'])
    def calculate():
        try:
            num1 = int(request.args.get('num1'))
            num2 = int(request.args.get('num2'))
            result = num1 + num2
            # 返回 JSON 格式的结果
            return jsonify({"status": "success", "result": result})
        except (ValueError, TypeError):
            return jsonify({"status": "error", "message": "Invalid parameters"}), 400
    if __name__ == '__main__':
        # 在生产环境中,应该使用 WSGI 服务器如 Gunicorn
        app.run(port=5000)

    启动服务: python api_server.py

  2. 在 LoadRunner 脚本中调用 Web 服务 使用 LoadRunner 的 Web 函数(如 web_reg_save_param, web_custom_request)来发送 HTTP 请求。

    #include "lrunet.h"
    #include "web_api.h" // 需要包含 Web 相关的头文件
    Action()
    {
        int a = 100;
        int b = 200;
        char url[256];
        char response_body[4096];
        // 构建请求 URL
        sprintf(url, "http://localhost:5000/calculate?num1=%d&num2=%d", a, b);
        // 发送 HTTP GET 请求
        web_custom_request(
            "call_python_api",
            "URL={"
            "https://localhost:5000/calculate?num1=100&num2=200"
            "}"
            "Method=GET"
            "Resource=0"
            "RecContentType=application/json"
            "EncType=application/json"
            "Snapshot=t1.inf"
            "Referer="
            "Mode=HTTP"
            "Body="
            );
        // 你可以使用 web_reg_save_param 来从响应中提取结果
        // 从 JSON 中提取 "result" 字段
        web_reg_save_param("api_result",
            "LB=\"result\":",
            "RB=,",
            "Search=Body",
            LAST);
        // 再次发送请求以触发参数保存
        web_custom_request(
            "call_python_api_to_save_param",
            "URL={"
            "https://localhost:5000/calculate?num1=100&num2=200"
            "}"
            "Method=GET"
            "Resource=0"
            "RecContentType=application/json"
            "EncType=application/json"
            "Snapshot=t2.inf"
            "Referer="
            "Mode=HTTP"
            "Body="
            );
        lr_output_message("API result parameter: %s", lr_eval_string("{api_result}"));
        return 0;
    }

优点

  • 解耦:LoadRunner 测试逻辑与 Python 业务逻辑完全分离。
  • 高性能:Web 服务可以持续运行,避免了重复创建进程的开销,适合高并发。
  • 可扩展性强:Python 服务可以轻松访问数据库、调用其他微服务等。
  • 功能强大:可以传递复杂的数据结构(如 JSON)。

缺点

  • 架构复杂:需要额外部署和管理一个 Web 服务。
  • 延迟:增加了网络通信的延迟。

使用 LoadRunner 的 Extension (不推荐)

LoadRunner 有一个 Extension 功能,允许你将其他语言的代码(包括 Python)编译成 DLL,然后在 LoadRunner 中调用,这种方法非常复杂,需要:

  1. 将 Python 代码封装成 C 兼容的函数。
  2. 使用工具(如 Cython)将其编译成 DLL。
  3. 在 LoadRunner 中声明并调用这个 DLL 函数。

为什么不推荐?

  • 极其复杂:配置过程繁琐,容易出错。
  • 维护困难:代码逻辑不直观,调试困难。
  • 依赖管理:需要确保 LoadRunner 运行环境能找到 Python 的 DLL 和依赖库。
  • 性能提升有限:相比 lr_system_call,启动进程的开销可能被 C 调用的开销抵消。

除非有非常特殊的需求(需要将 Python 逻辑深度集成到 LoadRunner 的内核中),否则应避免使用此方法。


总结与选择建议

方法 优点 缺点 适用场景
lr_system_call 简单、直接、无需额外服务 有进程开销,不适合超高并发;路径和环境依赖 快速原型、简单数据处理、一次性任务
Web 服务/API 高性能、高并发、解耦、可扩展 架构复杂,需额外部署和管理服务 复杂业务逻辑、性能测试、需要长期维护的脚本
lr_eval_string 无需外部文件 仅限单行,可读性差,维护困难 极其简单的、一次性的命令行操作
Extension (DLL) 理论上集成度高 极其复杂,维护噩梦,不推荐 极其特殊的需求,几乎无实际应用场景

给你的建议:

  • 对于 90% 的需求:直接使用 lr_system_call,它是最简单、最直接的解决方案,足以应对大多数情况。
  • 对于复杂的、高性能的、需要长期维护的负载测试:投入精力搭建一个 Python Web 服务,虽然前期工作多一些,但从长远来看,它的优势非常明显。
  • 避免使用 Extension,除非你明确知道你在做什么并且有充分的理由。
分享:
扫描分享到社交APP
上一篇
下一篇