Skip to main content

Load & Stress Automation Freamework

Project description

LoadDensity

Python PyPI License: MIT Documentation

LoadDensity is a high-performance load & stress testing automation framework built on top of Locust. It provides a simplified wrapper around Locust's core functionality, enabling fast user spawning, flexible test configuration via templates and JSON-driven scripts, report generation in multiple formats (HTML / JSON / XML), a built-in GUI, remote execution via TCP socket server, and a callback mechanism for post-test workflows.

繁體中文 | 简体中文


Features

  • Simplified Locust Wrapper — Abstracts Locust's Environment, Runner, and User classes behind a clean, high-level API.
  • Two User Types — Supports both HttpUser and FastHttpUser (geventhttpclient-based, higher throughput).
  • Fast User Spawning — Scale to thousands of concurrent users with configurable spawn rate.
  • JSON-Driven Test Scripts — Define test scenarios as JSON files and execute them without writing Python code.
  • Action Executor — A built-in event-driven executor that maps action names to functions. Supports batch execution and file-driven execution.
  • Report Generation — Export test results in three formats:
    • HTML — Styled tables with success/failure records
    • JSON — Structured data for programmatic consumption
    • XML — Standard XML output for CI/CD integration
  • Request Hook — Automatically records every request (success and failure) with method, URL, status code, response body, headers, and errors.
  • Callback Executor — Chain a trigger function with a callback function for post-test workflows (e.g., run test then generate report).
  • TCP Socket Server — Remote execution server based on gevent. Accepts JSON commands over TCP to execute tests remotely.
  • Project Scaffolding — Auto-generate project directory structure with keyword templates and executor scripts.
  • Package Manager — Dynamically load external Python packages and register their functions into the executor at runtime.
  • GUI (Optional) — PySide6-based graphical interface with real-time log display, supporting English and Traditional Chinese.
  • CLI Support — Run tests, execute scripts, or scaffold projects directly from the command line.
  • Cross-Platform — Works on Windows, macOS, and Linux.

Installation

Basic (CLI & Library)

pip install je_load_density

With GUI Support

pip install je_load_density[gui]

This installs PySide6 and qt-material for the graphical interface.

Requirements

  • Python 3.10 or later
  • Locust (installed automatically as a dependency)

Quick Start

1. Using the Python API

from je_load_density import start_test

# Define user configuration and tasks
result = start_test(
    user_detail_dict={"user": "fast_http_user"},
    user_count=50,
    spawn_rate=10,
    test_time=10,
    tasks={
        "get": {"request_url": "http://httpbin.org/get"},
        "post": {"request_url": "http://httpbin.org/post"},
    }
)

Parameters:

Parameter Type Default Description
user_detail_dict dict User type configuration. {"user": "fast_http_user"} or {"user": "http_user"}
user_count int 50 Total number of simulated users
spawn_rate int 10 Number of users spawned per second
test_time int 60 Test duration in seconds. None for unlimited
web_ui_dict dict None Enable Locust Web UI, e.g. {"host": "127.0.0.1", "port": 8089}
tasks dict HTTP method to request URL mapping

2. Using JSON Script Files

Create a JSON file (test_scenario.json):

[
    ["LD_start_test", {
        "user_detail_dict": {"user": "fast_http_user"},
        "user_count": 50,
        "spawn_rate": 10,
        "test_time": 5,
        "tasks": {
            "get": {"request_url": "http://httpbin.org/get"},
            "post": {"request_url": "http://httpbin.org/post"}
        }
    }]
]

Execute from Python:

from je_load_density import execute_action, read_action_json

execute_action(read_action_json("test_scenario.json"))

3. Using the CLI

# Execute a single JSON script file
python -m je_load_density -e test_scenario.json

# Execute all JSON files in a directory
python -m je_load_density -d ./test_scripts/

# Execute an inline JSON string
python -m je_load_density --execute_str '[["LD_start_test", {"user_detail_dict": {"user": "fast_http_user"}, "user_count": 10, "spawn_rate": 5, "test_time": 5, "tasks": {"get": {"request_url": "http://httpbin.org/get"}}}]]'

# Scaffold a new project with templates
python -m je_load_density -c MyProject

4. Using the GUI

from je_load_density.gui.main_window import LoadDensityUI
from PySide6.QtWidgets import QApplication
import sys

app = QApplication(sys.argv)
window = LoadDensityUI()
window.show()
sys.exit(app.exec())

Report Generation

After running a test, generate reports from the recorded data:

from je_load_density import (
    generate_html_report,
    generate_json_report,
    generate_xml_report,
)

# HTML report — creates "my_report.html"
generate_html_report("my_report")

# JSON report — creates "my_report_success.json" and "my_report_failure.json"
generate_json_report("my_report")

# XML report — creates "my_report_success.xml" and "my_report_failure.xml"
generate_xml_report("my_report")

Advanced Usage

Action Executor

The executor maps string action names to callable functions. All built-in Python functions are also available.

from je_load_density import executor, add_command_to_executor

# Register a custom function
def my_custom_action(message):
    print(f"Custom: {message}")

add_command_to_executor({"my_action": my_custom_action})

# Execute actions programmatically
executor.execute_action([
    ["my_action", ["Hello World"]],
    ["print", ["Test complete"]],
])

Built-in executor actions:

Action Name Description
LD_start_test Start a load test
LD_generate_html Generate HTML fragments
LD_generate_html_report Generate full HTML report file
LD_generate_json Generate JSON data structure
LD_generate_json_report Generate JSON report files
LD_generate_xml Generate XML strings
LD_generate_xml_report Generate XML report files
LD_execute_action Execute a list of actions
LD_execute_files Execute actions from multiple files
LD_add_package_to_executor Dynamically load a package into the executor

Callback Executor

Chain a trigger function with a callback:

from je_load_density import callback_executor

def after_test():
    print("Test finished, generating report...")

callback_executor.callback_function(
    trigger_function_name="user_test",
    callback_function=after_test,
    user_detail_dict={"user": "fast_http_user"},
    user_count=10,
    spawn_rate=5,
    test_time=5,
    tasks={"get": {"request_url": "http://httpbin.org/get"}},
)

TCP Socket Server (Remote Execution)

Start a TCP server that accepts JSON commands:

from je_load_density import start_load_density_socket_server

# Start server (blocking)
start_load_density_socket_server(host="localhost", port=9940)

Send commands from a client:

import socket, json

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(("localhost", 9940))

command = json.dumps([
    ["LD_start_test", {
        "user_detail_dict": {"user": "fast_http_user"},
        "user_count": 10, "spawn_rate": 5, "test_time": 5,
        "tasks": {"get": {"request_url": "http://httpbin.org/get"}}
    }]
])
sock.send(command.encode("utf-8"))
response = sock.recv(8192)
print(response.decode("utf-8"))
sock.close()

Send "quit_server" to gracefully shut down the server.

Project Scaffolding

Generate a project with keyword templates and executor scripts:

from je_load_density import create_project_dir

create_project_dir(project_path="./my_tests", parent_name="LoadDensity")

This creates:

my_tests/
└── LoadDensity/
    ├── keyword/
    │   ├── keyword1.json    # FastHttpUser test template
    │   └── keyword2.json    # HttpUser test template
    └── executor/
        ├── executor_one_file.py   # Execute single keyword file
        └── executor_folder.py     # Execute all files in keyword/

Dynamic Package Loading

Load external packages and register their functions into the executor:

from je_load_density import executor

# Load a package and make its functions available as executor actions
executor.execute_action([
    ["LD_add_package_to_executor", ["my_custom_package"]]
])

Test Records

Access raw test records programmatically:

from je_load_density import test_record_instance

# After running a test
for record in test_record_instance.test_record_list:
    print(record["Method"], record["test_url"], record["status_code"])

for error in test_record_instance.error_record_list:
    print(error["Method"], error["test_url"], error["error"])

# Clear records
test_record_instance.clear_records()

Architecture

je_load_density/
├── __init__.py              # Public API exports
├── __main__.py              # CLI entry point
├── gui/                     # PySide6 GUI (optional dependency)
│   ├── main_window.py       # Main window (QMainWindow)
│   ├── main_widget.py       # Test parameter form & log panel
│   ├── load_density_gui_thread.py  # Background thread for tests
│   ├── log_to_ui_filter.py  # Log interceptor for GUI display
│   └── language_wrapper/    # i18n (English, Traditional Chinese)
├── wrapper/
│   ├── create_locust_env/   # Locust Environment & Runner setup
│   ├── start_wrapper/       # High-level start_test() entry point
│   ├── user_template/       # HttpUser & FastHttpUser wrappers
│   ├── proxy/               # User proxy container & configuration
│   └── event/               # Request hook (records all requests)
└── utils/
    ├── executor/            # Action executor (event-driven)
    ├── generate_report/     # HTML, JSON, XML report generators
    ├── test_record/         # Test record storage
    ├── socket_server/       # TCP server for remote execution
    ├── callback/            # Callback function executor
    ├── project/             # Project scaffolding & templates
    ├── package_manager/     # Dynamic package loading
    ├── json/                # JSON file read/write utilities
    ├── xml/                 # XML structure utilities
    ├── file_process/        # Directory file listing
    ├── logging/             # Logger instance
    └── exception/           # Custom exceptions & error tags

Tested Platforms

  • Windows 10 / 11
  • macOS 10.15 ~ 11 (Big Sur)
  • Ubuntu 20.04
  • Raspberry Pi 3B+

License

This project is licensed under the MIT License.

Contributing

See CONTRIBUTING.md for guidelines.

Links

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

je_load_density-0.0.66.tar.gz (65.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

je_load_density-0.0.66-py3-none-any.whl (95.0 kB view details)

Uploaded Python 3

File details

Details for the file je_load_density-0.0.66.tar.gz.

File metadata

  • Download URL: je_load_density-0.0.66.tar.gz
  • Upload date:
  • Size: 65.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.13

File hashes

Hashes for je_load_density-0.0.66.tar.gz
Algorithm Hash digest
SHA256 266fb013518281eb1fb0c5a8ce24a4924229907c959e884a5898d55e9a82c14f
MD5 09095517f49171970e814ad01d522f95
BLAKE2b-256 e4b6e8e09d5536a0df55b8fd14270c12c886f86fd08f35eb87f91d5c942cea2a

See more details on using hashes here.

File details

Details for the file je_load_density-0.0.66-py3-none-any.whl.

File metadata

File hashes

Hashes for je_load_density-0.0.66-py3-none-any.whl
Algorithm Hash digest
SHA256 810eef1a95a30682a9da8d36381f83b5b426385cc6a672a6d4feca0844778823
MD5 9089c65dcffc6125602326fee9e3583f
BLAKE2b-256 cbade278f6eb55409987c2e84d08708f2027f18d0ca71cb1fb39ad73da679a2f

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page