Slint UI Testing with Python
Use the Slint UI Testing module to launch a Slint application locally or on a remote machine via SSH, inspect its UI, trigger actions, and verify correct behaviour.
This documentation describes slint_testing 0.2.
Prerequisites
Section titled “Prerequisites”- Python 3 ↗
- uv ↗
- Slint based on commit 61acc0f31044419b95b78960529122c1d0d0f4d1 ↗ or newer.
Your application needs to be built with system testing support:
- For Rust applications, depend on the
i-slint-backend-selectorcrate and enable thesystem-testingfeature. - For C++ applications, set
SLINT_FEATURE_SYSTEM_TESTING=ONandSLINT_FEATURE_EXPERIMENTAL=ONin your CMake configuration.
In addition, the SLINT_EMIT_DEBUG_INFO=1 environment variable must be set
during the application build process. We anticipate that this requirement will
be lifted in favor of an easier mechanism in the future.
Installation
Section titled “Installation”slint_testing is distributed through Slint’s commercial package index at
testing.slint.dev. With your license you receive an access token; add the
following to your project’s pyproject.toml:
[[tool.uv.index]]name = "slint-private"url = "https://testing.slint.dev/t/<TOKEN>/"explicit = true
[tool.uv.sources]slint-testing = { index = "slint-private" }Then install with:
uv add slint-testingexplicit = true keeps PyPI as the default for everything else; only
slint-testing is resolved through Slint’s index.
If your repository is public and you’d rather not commit the token URL, move the
[[tool.uv.index]] block to ~/.config/uv/uv.toml and leave the
[tool.uv.sources] mapping in pyproject.toml.
Continuous integration
Section titled “Continuous integration”In CI, keep only the [tool.uv.sources] mapping in pyproject.toml and supply
the index through environment variables sourced from a repository secret. Point
uv at the token-free /simple/ endpoint and pass the token as a credential
rather than embedding it in the URL — that way it stays out of uv.lock, which
uv would otherwise pin the resolved index URL into. uv derives the credential
variable names from the index name (slint-private → SLINT_PRIVATE). For
GitHub Actions:
- uses: astral-sh/setup-uv@v6 with: enable-cache: true- run: uv sync env: UV_INDEX: "slint-private=https://testing.slint.dev/simple/" UV_INDEX_SLINT_PRIVATE_USERNAME: __token__ UV_INDEX_SLINT_PRIVATE_PASSWORD: ${{ secrets.SLINT_TESTING_TOKEN }}The token stays in the secret store, out of both pyproject.toml and uv.lock.
import slint_testing
with slint_testing.Application(["/path/to/my_app"]) as aut: window = aut.first_window
root_element = window.root_element celsius_field = root_element.query_descendants().match_id("App::celsius-input").find_first() convert_button = root_element.query_descendants().match_id("App::convert-button").find_first() farenheit_field = root_element.query_descendants().match_id("App::farenheit-input").find_first()
celsius_field.accessible_value = "100" convert_button.invoke_accessible_default_action()
assert farenheit_field.accessible_value == 212The slint_testing module provides an Application class, which
wraps the Application Under Test (AUT). Construct it with the command line
arguments needed to launch the compiled application, and use it with Python’s
with ↗ statement.
Before entering your block, the application is launched and slint_testing
waits until the first window is shown and connected.
Fetch the Window from the Application, and then its
root_element. Use query_descendants
to initiate a query into the entire tree of elements, refine it for example via
match_id and finally obtain Element
references to the UI elements by calling find_first
or find_all.
Use Element‘s API to change state via accessible actions, verify
size and position, as well as accessible properties.
Networking
Section titled “Networking”The slint_testing module and the AUT are connected via a TCP connection and
exchange messages. slint_testing creates a listening TCP socket and passes the
address to the AUT via the SLINT_TEST_SERVER environment variable. The AUT,
when enabled for system testing, will automatically attempt to connect to the
listening TCP socket when the first window is shown. This assumes readiness of
the application, similar to how visibility on the screen indicates readiness to
an end-user.
When launched via SSH, slint_testing configures SSH to open a listening socket
on the remote side at port 8091 and configures a remote tunnel to forward to the
local socket slint_testing created.
© 2026 SixtyFPS GmbH