pytest-appium-scheduler
pytest-appium-scheduler is a pytest plugin for Appium test execution with:
- device-aware scheduling
pytest-xdistparallel executionfunctionandsessiondriver lifecycle control- per-test device targeting via markers
- debug and trace logs for worker/device visibility
The package is published as pytest-appium-scheduler. After publishing, both of these forms work with pip:
pip install pytest-appium-scheduler
Features
distributedmode: spread Appium tests across available devicesallmode: run each Appium test on every matching device@pytest.mark.device(...)and@pytest.mark.devices(...)- shared device pool with worker-safe leasing
driveranddevicefixtures- extensible hooks:
pytest_appium_create_driverpytest_appium_modify_caps
- compact debug output via
--appium-debug - verbose lifecycle tracing via
--appium-trace
Installation
pip install pytest_appium_scheduler
This installs:
pytestpytest-xdistPyYAMLappium-python-client
Quick Start
Create a device config, for example from device.example.yaml:
devices:
- name: emulator-5554
url: http://127.0.0.1:4723
caps:
platformName: Android
automationName: UiAutomator2
udid: emulator-5554
systemPort: 8201
appPackage: com.android.settings
appActivity: .Settings
- name: emulator-5556
url: http://127.0.0.1:4723
caps:
platformName: Android
automationName: UiAutomator2
udid: emulator-5556
systemPort: 8202
appPackage: com.android.settings
appActivity: .Settings
Write tests:
import pytest
def test_open_app(driver):
assert driver.session_id
def test_device_fixture(device):
assert device.name
@pytest.mark.device("emulator-5556")
def test_only_on_specific_device(driver):
assert driver.session_id
@pytest.mark.device(platform="Android")
def test_only_android(driver):
assert driver.session_id
class TestNoDevice:
def test_plain_pytest_case(self):
assert True
Run in distributed mode:
pytest tests \
--appium-config=device.yaml \
--appium-mode=distributed \
-n 2
Run in all mode:
pytest tests \
--appium-config=device.yaml \
--appium-mode=all \
-n 2
Scheduling Modes
distributed
Use devices as a shared execution pool.
- Appium tests are scheduled onto matching devices
- when workers are more than devices, extra workers can stay idle
- non-Appium tests can still run on idle workers
- when workers are fewer than devices, workers will rotate across devices instead of permanently starving one
all
Run every matching Appium test on every matching device.
- each device gets its own execution stream
- workers do not compete for the same device at the same time
- non-Appium tests can still run on idle workers
Fixtures
driver
Provides an Appium driver.
device
Provides the selected device model:
def test_device(device):
assert device.name
assert device.url
assert device.caps
Markers
Limit a test to one or more devices:
@pytest.mark.device("pixel_7")
def test_only_pixel(driver):
...
@pytest.mark.devices(["pixel_7", "iphone_14"])
def test_specific_devices(driver):
...
@pytest.mark.device(platform="iOS")
def test_only_ios(driver):
...
Behavior:
- unmarked tests: all configured devices are eligible
- unknown device marker: skipped with warning
- unmatched filter: skipped with warning
CLI Options
--appium-mode=distributed|all
--appium-config=PATH
--appium-device=NAME
--appium-driver-scope=function|session
--appium-retry-session=1
--appium-debug
--appium-trace
Useful examples
Select one device only:
pytest tests \
--appium-config=device.yaml \
--appium-device=huawei_p60
Reuse one driver per device session:
pytest tests \
--appium-config=device.yaml \
--appium-driver-scope=session
Show compact scheduling logs:
pytest tests \
--appium-config=device.yaml \
--appium-mode=distributed \
--appium-debug \
-n 2 -q -s
Show verbose lifecycle trace:
pytest tests \
--appium-config=device.yaml \
--appium-mode=distributed \
--appium-trace \
-n 2 -q -s
Custom Hooks
Modify capabilities
def pytest_appium_modify_caps(caps):
updated = dict(caps)
updated["newCommandTimeout"] = 120
return updated
Create your own driver
pytest_appium_modify_caps is applied before pytest_appium_create_driver, so your custom driver hook receives the updated capabilities.
def pytest_appium_create_driver(device):
from appium import webdriver
from appium.options.common.base import AppiumOptions
options = AppiumOptions()
options.load_capabilities(device.caps)
return webdriver.Remote(device.normalized_url(), options=options)
Debug Output
With --appium-debug:
[appium] gw0 target=huawei_p60 device=huawei_p60 PASSED tests/test_real_device.py::test_open_app session-123
With --appium-trace:
[pytest-appium-scheduler] action=device-acquire worker=gw0 target=huawei_p60 device=huawei_p60 details=nodeid=...
Development
Create a local environment:
python3 -m venv .venv
source .venv/bin/activate
pip install -e .
Run tests:
.venv/bin/python -m pytest tests/test_plugin.py -q
Build distributions:
.venv/bin/python -m pip install build
.venv/bin/python -m build
License
MIT. See LICENSE.
Metadata
Release files for pytest-appium-scheduler 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| pytest_appium_scheduler-0.1.1.tar.gz | 22.1 kB | Without provenance | Details for pytest_appium_scheduler-0.1.1.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| pytest_appium_scheduler-0.1.1-py3-none-any.whl | Python 3 | none | any | Details for pytest_appium_scheduler-0.1.1-py3-none-any.whl |
Total release size: 43.5 kB
Release files / pytest_appium_scheduler-0.1.1.tar.gz
| Download URL | pytest_appium_scheduler-0.1.1.tar.gz |
|---|---|
| Size | 22.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
9270c32a75be3516fb6d64b2d6e2e44f8bcc67b49200cff130b90d34b9ec01de
|
|
BLAKE2b-256 checksum How to use checksums |
de5d3ec782ca31f4b32cdf87db8748de0b43c0cf9dd344cd8bc61bfee1c2886b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.10
|
Release files / pytest_appium_scheduler-0.1.1-py3-none-any.whl
| Download URL | pytest_appium_scheduler-0.1.1-py3-none-any.whl |
|---|---|
| Size | 21.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
300b1f9d7d8a7c285eda45fcd4c7e115cc8238c2313ba4e78a153988e8c9a718
|
|
BLAKE2b-256 checksum How to use checksums |
1e8025ec626ba1d0536be5e49bbe3a304719691ca87f062e53db7e8d64413c6e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.10
|
Security for pytest-appium-scheduler 0.1.1
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.
No provenance found
None of the files in this release were uploaded with provenance metadata.
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.