Executar testes em paralelo em múltiplos dispositivos reduz significativamente o tempo total de execução. O Appium suporta múltiplas sessões simultâneas desde que cada uma use uma porta diferente (ou o mesmo servidor com conexões distintas).
O segredo está em usar ThreadLocal<AppiumDriver> para garantir que cada thread tenha seu próprio driver isolado.
package utils;
import io.appium.java_client.AppiumDriver;
public class DriverManager {
private static final ThreadLocal<AppiumDriver> driverThread = new ThreadLocal<>();
public static AppiumDriver getDriver() {
return driverThread.get();
}
public static void setDriver(AppiumDriver driver) {
driverThread.set(driver);
}
public static void removeDriver() {
driverThread.remove();
}
}package base;
import io.appium.java_client.AppiumDriver;
import io.appium.java_client.android.AndroidDriver;
import io.appium.java_client.android.options.UiAutomator2Options;
import org.testng.ITestResult;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Parameters;
import utils.DriverManager;
import utils.ScreenshotHelper;
import java.net.MalformedURLException;
import java.net.URL;
public class BaseTest {
@BeforeMethod
@Parameters({"deviceName", "appiumPort"})
public void setUp(String deviceName, String appiumPort) throws MalformedURLException {
UiAutomator2Options options = new UiAutomator2Options();
options.setDeviceName(deviceName);
options.setApp(System.getProperty("user.dir") + "/src/test/resources/apps/meuapp.apk");
options.setAutoGrantPermissions(true);
AppiumDriver driver = new AndroidDriver(
new URL("http://localhost:" + appiumPort),
options
);
DriverManager.setDriver(driver);
}
@AfterMethod
public void tearDown(ITestResult result) {
if (result.getStatus() == ITestResult.FAILURE) {
ScreenshotHelper.capturar(DriverManager.getDriver(), result.getName());
}
DriverManager.getDriver().quit();
DriverManager.removeDriver();
}
}<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd">
<suite name="Suite Paralela" parallel="tests" thread-count="2">
<test name="Android - Emulador 1">
<parameter name="deviceName" value="emulator-5554"/>
<parameter name="appiumPort" value="4723"/>
<classes>
<class name="tests.LoginTest"/>
</classes>
</test>
<test name="Android - Emulador 2">
<parameter name="deviceName" value="emulator-5556"/>
<parameter name="appiumPort" value="4725"/>
<classes>
<class name="tests.LoginTest"/>
</classes>
</test>
</suite>Para cada dispositivo, inicie um servidor Appium em uma porta diferente:
# Terminal 1
appium --port 4723
# Terminal 2
appium --port 4725O Appium 2.x suporta múltiplas sessões simultâneas em um único servidor. Você pode usar um único servidor e apenas variar o deviceName e udid:
<suite name="Suite Paralela" parallel="tests" thread-count="2">
<test name="Dispositivo 1">
<parameter name="deviceName" value="emulator-5554"/>
<parameter name="appiumPort" value="4723"/>
<classes><class name="tests.LoginTest"/></classes>
</test>
<test name="Dispositivo 2">
<parameter name="deviceName" value="emulator-5556"/>
<parameter name="appiumPort" value="4723"/>
<classes><class name="tests.LoginTest"/></classes>
</test>
</suite>No Android Studio, abra o AVD Manager (Device Manager) e crie vários emuladores.
Ou via linha de comando:
# Listar AVDs disponíveis
emulator -list-avds
# Iniciar emuladores em portas específicas
emulator -avd Pixel_6_API_33 -port 5554 &
emulator -avd Pixel_6_API_33 -port 5556 &- Use
ThreadLocalpara isolar o driver por thread — evita condições de corrida - Sempre chame
DriverManager.removeDriver()notearDownpara evitar memory leak - Limite o paralelismo ao número de dispositivos disponíveis — mais threads que dispositivos causa falhas
- Em CI, use Cloud Testing (BrowserStack, Sauce Labs) para paralelismo escalável
Ir para: CI/CD