Skip to main content

Pytest plugin for Appium device scheduling and driver lifecycle management.

Project description

pytest-appium-scheduler

pytest-appium-scheduler is a pytest plugin for Appium test execution with:

  • device-aware scheduling
  • pytest-xdist parallel execution
  • function and session driver 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

  • distributed mode: spread Appium tests across available devices
  • all mode: run each Appium test on every matching device
  • @pytest.mark.device(...) and @pytest.mark.devices(...)
  • shared device pool with worker-safe leasing
  • driver and device fixtures
  • extensible hooks:
    • pytest_appium_create_driver
    • pytest_appium_modify_caps
  • compact debug output via --appium-debug
  • verbose lifecycle tracing via --appium-trace

Installation

pip install pytest_appium_scheduler

This installs:

  • pytest
  • pytest-xdist
  • PyYAML
  • appium-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.

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

pytest_appium_scheduler-0.1.1.tar.gz (22.1 kB view details)

Uploaded Source

Built Distribution

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

pytest_appium_scheduler-0.1.1-py3-none-any.whl (21.4 kB view details)

Uploaded Python 3

File details

Details for the file pytest_appium_scheduler-0.1.1.tar.gz.

File metadata

  • Download URL: pytest_appium_scheduler-0.1.1.tar.gz
  • Upload date:
  • Size: 22.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.10

File hashes

Hashes for pytest_appium_scheduler-0.1.1.tar.gz
Algorithm Hash digest
SHA256 9270c32a75be3516fb6d64b2d6e2e44f8bcc67b49200cff130b90d34b9ec01de
MD5 b683a102aceb74b324a565b676118300
BLAKE2b-256 de5d3ec782ca31f4b32cdf87db8748de0b43c0cf9dd344cd8bc61bfee1c2886b

See more details on using hashes here.

File details

Details for the file pytest_appium_scheduler-0.1.1-py3-none-any.whl.

File metadata

File hashes

Hashes for pytest_appium_scheduler-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 300b1f9d7d8a7c285eda45fcd4c7e115cc8238c2313ba4e78a153988e8c9a718
MD5 dd70ea627028b9f076e3de99a3d6e129
BLAKE2b-256 1e8025ec626ba1d0536be5e49bbe3a304719691ca87f062e53db7e8d64413c6e

See more details on using hashes here.

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