Skip to main content

bsm-test-utils

A robust test utility package designed to simulate Minecraft Bedrock Dedicated Server environments. It is primarily used for writing comprehensive integration tests (e.g., testing the Bedrock Server Manager) by providing programmatic fixtures, HTTP download mocking, and dynamic asset generation.

Features

  • Dynamic Server Releases: Generate zip files mimicking official Bedrock Server releases (custom versions, preview tags).
  • Dynamic Add-on Generation: Programmatically build behavior packs, resource packs, and script packs. Generate them as directories or .mcpack zip files with optionally invalid configurations for edge-case testing.
  • Bundle Support: Create .mcaddon (bundled packs) and .mcworld (worlds embedded with custom level.dat and packs).
  • Mock HTTP Server: A lightweight, multithreaded http.server designed for testing download functionality directly in pytest, avoiding external network calls.
  • Pytest Fixtures: Seamlessly integrated fixtures to use these tools out-of-the-box in your test suites.

Installation

pip install bsm-test-utils

Setup for Pytest

To use the built-in Pytest fixtures automatically in your tests, register them in your conftest.py file:

# conftest.py
pytest_plugins = ["bsm_test_utils.fixtures"]

Detailed Pytest Guide

The following examples demonstrate how to use bsm-test-utils to write powerful, isolated integration tests for Bedrock tooling.

1. Mocking a Server Download

Instead of hitting the real Minecraft download servers during your tests, use the mock_http_server and dummy_server_zip fixtures to generate a fake release and serve it locally.

import urllib.request
import zipfile
from pathlib import Path

def test_download_and_extract_server(mock_http_server, dummy_server_zip, tmp_path):
    # 1. Generate the zip file directly into the mock server's directory
    # The factory returns the Path to the generated zip file.
    zip_path = dummy_server_zip(
        target_dir=mock_http_server.directory,
        version="1.20.10.01",
        is_preview=False
    )

    # 2. Construct the URL to the mock server
    download_url = f"{mock_http_server.url}/{zip_path.name}"

    # 3. Simulate your application's download logic
    dest_path = tmp_path / zip_path.name
    urllib.request.urlretrieve(download_url, dest_path)

    # 4. Verify the download and extract it
    assert dest_path.exists()

    extract_dir = tmp_path / "server"
    with zipfile.ZipFile(dest_path, "r") as zf:
        zf.extractall(extract_dir)

    # The dummy server contains standard config files and the platform binary
    assert (extract_dir / "server.properties").exists()
    assert (extract_dir / "allowlist.json").exists()
    assert (extract_dir / "permissions.json").exists()
    assert (extract_dir / "behavior_packs").is_dir()

Included Server Configurations

The generated server zip automatically includes standard configuration files populated with default settings:

  • server.properties
  • allowlist.json (defaults to [])
  • permissions.json (defaults to [])

This enables you to write integration tests that rely on parsing or managing these configuration files.

2. Testing Addon Management

You can inject pre-built valid or invalid addons to test how your application handles importing or reading them. The package includes multiple tools to simulate edge cases like corrupt configurations or broken JSON formatting.

  • invalid_behavior_pack: Creates a valid JSON structure but omits required fields (like the uuid).
  • invalid_json_pack: Creates a fundamentally corrupt JSON manifest with syntax errors.
import json
import pytest

def test_addon_manifest_reading(valid_behavior_pack, invalid_behavior_pack, invalid_json_pack):
    # valid_behavior_pack is a Path to an extracted directory
    with open(valid_behavior_pack / "manifest.json") as f:
        manifest = json.load(f)
    assert "uuid" in manifest["header"]
    assert manifest["modules"][0]["type"] == "data"

    # invalid_behavior_pack simulates a corrupt manifest (missing UUID)
    with open(invalid_behavior_pack / "manifest.json") as f:
        invalid_manifest = json.load(f)
    assert "uuid" not in invalid_manifest.get("header", {})

    # invalid_json_pack simulates a fundamentally corrupt JSON file
    with open(invalid_json_pack / "manifest.json") as f:
        with pytest.raises(json.JSONDecodeError):
            json.load(f)

3. Working with Bundles (.mcaddon / .mcworld)

If your application supports .mcaddon or .mcworld file uploads, you can use the built-in fixtures that provide generated .zip files under those extensions.

import zipfile

def test_mcaddon_extraction(valid_mcaddon_zip, tmp_path):
    # valid_mcaddon_zip is a Path to a .mcaddon file
    assert valid_mcaddon_zip.suffix == ".mcaddon"

    with zipfile.ZipFile(valid_mcaddon_zip, "r") as zf:
        # An .mcaddon usually contains multiple .mcpack files
        assert any(f.endswith(".mcpack") for f in zf.namelist())

def test_mcworld_import(valid_mcworld_zip, mock_http_server):
    # You can even move these bundles into the mock server for download testing
    import shutil
    dest = mock_http_server.directory / valid_mcworld_zip.name
    shutil.copy2(valid_mcworld_zip, dest)

    download_url = f"{mock_http_server.url}/{valid_mcworld_zip.name}"
    # ... assert your application handles the URL correctly

4. End-to-End Download Testing

For applications like bedrock-server-manager that scrape the official download endpoint, you can use the mock_bedrock_api fixture. It sets up a localized mock of /api/v1.0/download/links containing dynamically generated mock zips for stable and preview releases on both Linux and Windows.

import json
import urllib.request

def test_bedrock_api_mock(mock_bedrock_api):
    # The fixture yields the mock_http_server instance, but with the API already populated
    api_url = f"{mock_bedrock_api.url}/api/v1.0/download/links"

    # 1. Fetch the JSON as your manager would
    req = urllib.request.Request(api_url)
    with urllib.request.urlopen(req) as response:
        data = json.loads(response.read().decode())

    links = {item["downloadType"]: item["downloadUrl"] for item in data["result"]["links"]}

    # 2. Download a platform specific zip
    linux_url = links["serverBedrockLinux"]
    dest = mock_bedrock_api.directory / "downloaded.zip"
    urllib.request.urlretrieve(linux_url, dest)
    assert dest.exists()

Reference: Available Pytest Fixtures

Fixture Name Return Type Description
mock_http_server MockHTTPServer Yields a running multithreaded HTTP server bound to 127.0.0.1. Automatically cleans up after the test. Access the URL via .url and its root directory via .directory.
mock_bedrock_api MockHTTPServer Yields a mock_http_server pre-populated with a mocked /api/v1.0/download/links endpoint serving generated server zips.
dummy_server_zip Callable A factory function: def _factory(target_dir, version="...", is_preview=False, is_windows=None, filename=None). Returns a Path to the generated server zip.
valid_behavior_pack Path Path to a valid behavior pack directory.
invalid_behavior_pack Path Path to an invalid behavior pack directory (missing UUID).
invalid_json_pack Path Path to an invalid behavior pack directory with a fundamentally corrupt JSON manifest.
valid_resource_pack Path Path to a valid resource pack directory.
valid_behavior_pack_zip Path Path to a valid behavior pack .mcpack file.
valid_mcaddon_zip Path Path to a valid .mcaddon file (contains bundled behavior and resource packs).
valid_mcworld_zip Path Path to a valid .mcworld file (contains level.dat and embedded addons).

5. Interacting with the Dummy Server

The generated server binaries in bsm-test-utils are more than just empty files. When executed, they print logs mimicking exactly what the official Bedrock dedicated server outputs.

You can also use special arguments and standard input commands to mock specific behaviors:

  • Immediate Crash: Start the server with the --mock-crash argument to have it print a segfault message and immediately exit with code 1.
  • Runtime Crash: Send the string __DUMMY__ CRASH to the standard input while the server is running to simulate a random runtime panic (exits with code 1).
  • Player Events: Send __DUMMY__ PLAYER_JOIN <username> or __DUMMY__ PLAYER_LEAVE <username> to generate standard player connection/disconnection logs.
  • Graceful Shutdown: Sending the standard Bedrock stop command will trigger a normal shutdown sequence resulting in an exit code 0.

Asset Generation (Manual Usage)

If you need even more customization, you can import and use the generation functions directly without fixtures:

from bsm_test_utils import create_mcworld, create_behavior_pack, create_mcaddon

# 1. Create a behavior pack zip
create_behavior_pack("./packs", name="My BP", as_zip=True)

# 2. Create an mcaddon containing multiple custom packs
create_mcaddon(
    "./bundles",
    name="My Addon Bundle",
    packs=[
        {"name": "My Custom BP", "pack_type": "data"},
        {"name": "My Custom RP", "pack_type": "resources"}
    ]
)

# 3. Create a world with embedded addons
# When packs are provided, this will automatically read their manifests and generate
# `world_behavior_packs.json` and `world_resource_packs.json` linking to the embedded packs.
create_mcworld(
    "./worlds",
    name="My World",
    level_dat_content="custom binary data",
    packs=[
        {"name": "Embedded BP", "pack_type": "data"},
        {"name": "Embedded RP", "pack_type": "resources"}
    ]
)

Metadata

Release files for bsm-test-utils 1.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for bsm-test-utils 1.0.0
File Size Uploaded Provenance Actions
bsm_test_utils-1.0.0.tar.gz 3.2 MB With provenance Details for bsm_test_utils-1.0.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for bsm-test-utils 1.0.0
File Interpreter ABI Platform Actions
bsm_test_utils-1.0.0-py3-none-any.whl Python 3 none any Details for bsm_test_utils-1.0.0-py3-none-any.whl

Total release size: 6.5 MB

Release files / bsm_test_utils-1.0.0.tar.gz

Download URL bsm_test_utils-1.0.0.tar.gz
Size 3.2 MB
Tags Source
SHA-256 checksum
How to use checksums
7c33425a17eb0d00a058f5ff346e8aea701dff2b36b84a1cd0ba250bb7339e0a
BLAKE2b-256 checksum
How to use checksums
3078e82624f3014fb6ec47c8b4951dd7c28a387ce0984a941cd4bb6272485b6a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 15, 2026.

Transparency log

Release files / bsm_test_utils-1.0.0-py3-none-any.whl

Download URL bsm_test_utils-1.0.0-py3-none-any.whl
Size 3.2 MB
Tags Python 3
SHA-256 checksum
How to use checksums
fc0df4cf7e404a83f88f804a1ff280cac0ec2b3e96f4ab47409c6f1c41f59127
BLAKE2b-256 checksum
How to use checksums
9567ce37d264b248226f5aeaf41377db712a7ea64239114414fc6d9511d84dc3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 15, 2026.

Transparency log

Security for bsm-test-utils 1.0.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for bsm_test_utils-1.0.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 15, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page