我目前正在尝试通过并行测试来增强我们的测试自动化基础设施。我知道该怎么做,但我遇到了设备管理的问题。想象一下,我有 5 个不同的设备和 10 个测试,我想并行运行。每个测试都需要不同的时间,并且可能会在失败时再次运行。我现在可以为每个测试选择一个特定的设备,但我不想这样做。相反,我想要一段代码来为我决定哪个设备是免费的并使用该设备。我可以通过查找 Appium 服务器上的当前会话来做到这一点。在两个测试同时开始之前,这一切都很好。然后 UiAutomator2 为两个测试选择相同的设备,并且失败并出现期望
org.openqa.selenium.SessionNotCreatedException: Could not start a new session. Response code 500. Message: An unknown server-side error occurred while processing the command. Original error: The instrumentation process cannot be initialized.
我现在的问题是这里有人有在多个设备上并行测试的经验并可以建议我可以尝试的一些事情吗?我使用 Appium 作为服务器 Android 作为操作系统 Java 作为编程语言和 TestNG。
这是我的套装代码
<!DOCTYPE suite SYSTEM
"http://testng.org/testng-1.0.dtd" >
<suite name="FirstSuit" configfailurepolicy="continue" verbose="10" parallel="tests">
<test name="FirstTest">
<classes>
<class name="org.example.FirstAppiumTest"/>
</classes>
</test>
<test name="SecondTest">
<classes>
<class name="org.example.SecondAppiumTest"/>
</classes>
</test>
</suite>
这是我目前如何检查 busyDevices 的代码
private URL getHubUrl() {
URL remoteAddress = null;
try {
remoteAddress = new URL("http://127.0.0.1:4723/wd/hub");
} catch (MalformedURLException e) {
Assert.fail("Selenium Grid address is malformed. Exception message: ", e);
}
return remoteAddress;
}
public void setDriver() {
DesiredCapabilities caps = new DesiredCapabilities();
caps.setCapability("platformName", "android");
caps.setCapability("appium:automationName", "uiautomator2");
caps.setCapability("appium:appPackage", "com.example.exampleApp");
caps.setCapability("appium:appActivity", "com.example.exampleApp.frontend.MainActivity");
List<String> busyDevices = get_busyDevices("http://127.0.0.1:4723/wd/hub");
List<String> availableDevices = findIdleDevices(Constants.allDevices, busyDevices);
if (!availableDevices.isEmpty()) {
System.out.println("SecondTest running on " + availableDevices.getFirst());
caps.setCapability("appium:udid", availableDevices.getFirst());
} else {
throw new RuntimeException("No device found");
}
driver = new AndroidDriver(getHubUrl(), caps);
}
public List<String> findIdleDevices(List<String> allDevices, List<String> busyDevices) {
return allDevices.stream()
.filter(device -> !busyDevices.contains(device))
.collect(Collectors.toList());
}
private static List\<String\> get_busyDevices(String appiumServerUrl) {
try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
HttpGet request = new HttpGet(appiumServerUrl + "/sessions");
try (CloseableHttpResponse response = httpClient.execute(request)) {
String responseString = EntityUtils.toString(response.getEntity());
JSONObject jsonResponse = new JSONObject(responseString);
return extract_Udid(jsonResponse);
}
} catch (Exception e) {
e.printStackTrace();
return new ArrayList<>();
}
}
public static List<String> extract_Udid(JSONObject jsonResponse) {
JSONArray valueArray = jsonResponse.getJSONArray("value");
List<String> udidList = new ArrayList<>();
for (int i = 0; i < valueArray.length(); i++) {
JSONObject capabilities = valueArray.getJSONObject(i).getJSONObject("capabilities");
String udid = capabilities.getString("udid");
if (!udidList.contains(udid)) {
udidList.add(udid);
}
}
return udidList;
}
经过一番挖掘,我发现 Appium 插件“Device Farm”正是我想要的。它会自动处理会话并选择下一个可用的设备。