Before anything, spring up two different servers running on different ports.
appium --port 4723
and
appium --port 4724
Now we have two servers running on different terminal windows.
conftest.py
import pytest
import logging
import time
import random
from appium import webdriver
from typing import Any, Dict
from appium.options.common.base import AppiumOptions
from appium.webdriver.common.appiumby import AppiumBy
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import ElementNotVisibleException, NoSuchElementException
@pytest.fixture(scope="function")
def driver1():
# Set desired capabilities for the Android emulator
cap: Dict[str, Any] = {
"platformName": "Android",
"appium:automationName": "uiautomator2",
"appium:platformVersion": "12",
"udid": "---",
"port": 4723,
"appium:appPackage": "---",
"appium:appActivity": "---"
}
url = "http://localhost:4723"
driver = webdriver.Remote(url, options=AppiumOptions().load_capabilities(cap))
return driver
@pytest.fixture(scope="function")
def driver2():
# Set desired capabilities for the Android emulator
cap: Dict[str, Any] = {
"platformName": "Android",
"appium:automationName": "uiautomator2",
"appium:platformVersion": "12",
"appium:udid": "---",
"appium:appPackage": "---",
"port": 4724,
"appium:appActivity": "---"
}
url = "http://localhost:4724"
driver = webdriver.Remote(url, options=AppiumOptions().load_capabilities(cap))
return driver
the fixtures are going to return a different driver that is going to interact with their respective ports.
test_script1.py
our example test script 1.
import time
def test_script2(driver2):
driver2.tap([(534,721)])
time.sleep(2)
driver2.quit()
test_script2.py
our example test script 2.
import time
def test_script1(driver1):
driver1.tap([(534,721)])
time.sleep(2)
driver1.quit()
As you can see, these example scripts don’t do much, but the possibilities are endless.
Running Sequentially
Since we’re using pytest, let’s just run pytest from the project directory.
pytest -v
-v is for verbose.
You should see that the scripts are running one device after the other.
Running Parallelly
Let’s use pytest-xdist which schedules tests via LoadScheduling.
Now if we run the below command to trigger the pytest framework, we should be able to run both the test scripts parallelly.
pytest -v -n 2
-n is for the number of workers. since we are using only two devices for this example, let’s just use 2 runners
VOILA!
the output would look something like this
PS C:> pytest -v -n 2
================================================================================================== test session starts ==================================================================================================
platform win32 -- Python 3.12.1, pytest-8.3.5, pluggy-1.5.0 -- C:\Users\r.charan\Documents\appium_parallel\venv\Scripts\python.exe
cachedir: .pytest_cache
rootdir: C:
plugins: xdist-3.7.0
2 workers [2 items]
scheduling tests via LoadScheduling
test_script2.py::test_script2
test_script1.py::test_script1
[gw0] [ 50%] PASSED test_script1.py::test_script1
[gw1] [100%] PASSED test_script2.py::test_script2
and the test scripts should be running parallelly on both the devices.