Skip to content

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.

Your application needs to be built with system testing support:

  • For Rust applications, depend on the i-slint-backend-selector crate and enable the system-testing feature.
  • For C++ applications, set SLINT_FEATURE_SYSTEM_TESTING=ON and SLINT_FEATURE_EXPERIMENTAL=ON in 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.

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:

Terminal window
uv add slint-testing

explicit = 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.

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-privateSLINT_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 == 212

The 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.

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