Skip to main content

Pytest-like test framework for LSL — drives sakura-lslc and sakura-slemu

Project description

sakura-lsltest

CI License: MIT GitHub release

A pytest-style test framework for LSL — by Sakura Studios, IKE.

sakura-lsltest drives sakura-lslc (the offline compiler) and sakura-slemu (the headless region emulator) so you can write fully automated unit & integration tests against real LSL source — no viewer, no in-world prim, no manual button-clicking.

import lsltest

ALICE = "22222222-2222-2222-2222-222222222222"

@lsltest.compile_ok("scripts/vendor.lsl")
def test_vendor_compiles(): pass

@lsltest.scene(
    scripts=["scripts/vendor.lsl"],
    owner=("11111111-...", "Shop", 100),
    avatars=[(ALICE, "Alice", 50)],
    fixtures=[("https://api/x", 200, '{"ok":true}')],
)
def test_alice_buys_apple(world):
    world.touch(link=1, avatar=ALICE)
    world.assert_dialog_open(ALICE)
    world.dialog_reply(avatar=ALICE, button="Apple")
    world.assert_hud(link=1, substring="Sold Apple")
    world.assert_said(kind="region-to", channel=0, substring="thanks")
    world.assert_balance(ALICE, 51)
$ lsltest run examples/
  PASS  test_basics.py::test_broken_rejected
  PASS  test_basics.py::test_hello_compiles
  PASS  test_vendor.py::test_alice_buys_apple
  PASS  test_vendor.py::test_bob_cancels

Result: 76 passing / 76 tests

What you can assert

Concern API
Compiles cleanly @lsltest.compile_ok(path)
Fails to compile (with diagnostic) @lsltest.compile_fails(path, diagnostic=...)
Compiles but warns @lsltest.compile_warns(path, warning=...)
Touch / dialog / textbox / listen / IM world.touch / dialog_reply / textbox_reply / listen
Player pays the object world.money_in(avatar=, amount=)
External system calls llRequestURL endpoint world.http_in(url=, method=, body=)
Attach / detach as HUD world.attach / detach
HUD floating text world.assert_hud(link=, substring=)
What was said (any channel) world.assert_said(kind=, channel=, substring=)
Dialog open for an avatar world.assert_dialog_open(avatar=)
Avatar's L$ balance world.assert_balance(avatar, amount) / world.balance(avatar)
Arbitrary event predicate world.first("dialog", to=ALICE)
Inspect entire event stream world.events("hud"), world.chat()

Install

From PyPI

pip install sakura-lsltest

(plus the two C binaries — lslc and slemu from the sibling repos, either built locally with make or installed system-wide.)

Arch Linux (AUR)

yay -S sakura-lsltest            # latest tagged release
yay -S sakura-lsltest-git        # follow main

See packaging/aur/README.md for the PKGBUILDs.

From source (editable)

git clone https://github.com/Sakura-Studios-IKE/sakura-lsltest.git
cd sakura-lsltest
pip install -e .

Run

lsltest run tests/                # discover and run all test_*.py
lsltest run tests/ -k vendor      # filter by name substring
lsltest run tests/ -v             # show failure details
lsltest run tests/ --keep         # keep slemu artefacts for inspection
lsltest run tests/ --lslc ./lslc --slemu ./slemu

Inside Python, the framework is a regular library — you can also call World(), Scene(), and the decorators from a pytest run, a Hypothesis strategy, a Makefile, or a CI step.

How it works

  1. Compile. For each test, lsltest calls lslc -c <path> and parses the result; failures bubble up as Python assertion errors with the exact diagnostic stderr.
  2. Scene setup. It writes a world.cfg file describing your avatars, owners, groups, and HTTP fixtures, plus a session.cmds file listing the player actions you queued.
  3. Drive slemu. It launches slemu --json-events --config … --commands … with all your compiled .lslbc. Every event slemu emits (chat, HUD update, dialog opening, money transfer, link-message, HTTP request) becomes a parseable JSON line.
  4. Verify. Any world.assert_*(…) calls embed assertions into the command file; slemu evaluates them in line with the rest of the simulation. Any failures (and any Python-side post-run checks via world.balance(…) / world.events(…) / world.first(…)) raise LsltestError which the runner reports with full context.

Because every assertion is observable through the JSON event stream, your tests are deterministic, reproducible, and CI-friendly — same artefacts, same answers, every run.

Project layout

sakura-lsltest/
├── README.md
├── LICENSE                 MIT
├── pyproject.toml
├── Makefile
├── src/lsltest/
│   ├── __init__.py        public API
│   ├── core.py            decorators, World, Scene, runner
│   └── __main__.py        `python -m lsltest` / `lsltest` CLI
└── examples/
    ├── scripts/           example LSL sources
    ├── test_basics.py     compile-only tests
    └── test_vendor.py     interactive scene tests

Status

sakura-lsltest is the test harness in Sakura Studios' five-tool open-source LSL toolchain:

  1. sakura-lslc — offline compiler.
  2. sakura-slemu — headless region emulator.
  3. sakura-lsltest (this repo) — automated test harness.
  4. sakura-lsldb — gdb-style CLI debugger.
  5. sakura-intellij-lsl — IntelliJ plugin.

Author / Attribution

Authored and maintained by Shiho Sakura (@ShihoSakura) on behalf of Sakura Studios, IKE.

License

MIT — see LICENSE.

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

sakura_lsltest-1.0.0.tar.gz (12.8 kB view details)

Uploaded Source

Built Distribution

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

sakura_lsltest-1.0.0-py3-none-any.whl (11.5 kB view details)

Uploaded Python 3

File details

Details for the file sakura_lsltest-1.0.0.tar.gz.

File metadata

  • Download URL: sakura_lsltest-1.0.0.tar.gz
  • Upload date:
  • Size: 12.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for sakura_lsltest-1.0.0.tar.gz
Algorithm Hash digest
SHA256 ca548736ec62ba782dffff840346eb4721603b22b9f35ef69907e284c951c8fb
MD5 ec2decfc1a99fcd6971cd225717c48c6
BLAKE2b-256 9cdcd91c9a32411fad1ccbb3a9b5d43ef0e4f15d99e7749863117d1932a77616

See more details on using hashes here.

Provenance

The following attestation bundles were made for sakura_lsltest-1.0.0.tar.gz:

Publisher: ci.yml on Sakura-Studios-IKE/sakura-lsltest

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file sakura_lsltest-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: sakura_lsltest-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 11.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for sakura_lsltest-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 a2f1a3a64543fefc792a1278d3180e13f42d3921dbdedb96a911240e232e0472
MD5 3e468c5b2c8f2b01ece965af84176044
BLAKE2b-256 f87050e6f1e967e76b94d6f7ecc08c540bf87318111c10c42ea70e33cbb0993c

See more details on using hashes here.

Provenance

The following attestation bundles were made for sakura_lsltest-1.0.0-py3-none-any.whl:

Publisher: ci.yml on Sakura-Studios-IKE/sakura-lsltest

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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