提问人:cdub 提问时间:11/15/2023 最后编辑:Krishnan Mahadevancdub 更新时间:11/24/2023 访问量:36
如何避免org.openqa.selenium.WebDriverException:原始错误:套接字挂起?
How can I avoid org.openqa.selenium.WebDriverException: Original error: socket hang up?
问:
我正在使用 Appium 2.2.1、Java 11、TestNG 和 Cucumber 运行测试自动化套件。
我在测试执行过程中不断遇到问题。这通常也会在接下来的几个场景中犯规。org.openqa.selenium.WebDriverException: org.openqa.selenium.WebDriverException: An unknown server-side error occurred while processing the command. Original error: Could not proxy command to the remote server. Original error: socket hang up
我知道解决这个问题的常用方法是运行 和 ,但是我该如何设置我的代码来避免这个错误。adb uninstall io.appium.uiautomator2.server.test
adb uninstall io.appium.uiautomator2.server
以下是我在真实设备上运行测试的方式。注意:即使我只是在一台设备上运行单个线程,也会引发上述错误。
运行并行测试.java
@CucumberOptions(
features = "classpath:features",
glue = {"stepdefs"}
)
public class RunParallelTests extends AbstractTestNGCucumberTests {
private final DesiredCapabilitiesUtil desiredCapabilitiesUtil = new DesiredCapabilitiesUtil();
private final AppiumServiceBuilderUtil appiumServiceBuilderUtil = new AppiumServiceBuilderUtil();
protected AppiumDriverLocalService service;
@BeforeTest(alwaysRun = true)
public void startAppiumServer(){
//System.out.println("Building Appium Server");
service = appiumServiceBuilderUtil.buildAppiumService();
System.out.println("Starting Appium Server");
service.clearOutPutStreams();
service.start();
}
@BeforeMethod
@Parameters({"deviceOS"})
public void setup(String deviceOS){
service.isRunning();
URL serviceURL = service.getUrl();
switch (deviceOS) {
case "iOS":
//System.out.println("Initializing iOS Driver");
DesiredCapabilities iosCaps = desiredCapabilitiesUtil.getDesiredCapabilities(deviceOS);
ThreadLocalDriver.setTLDriver(new IOSDriver(serviceURL, iosCaps));
break;
case "Android":
//System.out.println("Initializing Android Driver");
DesiredCapabilities androidCaps = desiredCapabilitiesUtil.getDesiredCapabilities(deviceOS);
ThreadLocalDriver.setTLDriver(new AndroidDriver(serviceURL, androidCaps));
if (((AndroidDriver)ThreadLocalDriver.getTLDriver()).isDeviceLocked()){
((AndroidDriver)ThreadLocalDriver.getTLDriver()).unlockDevice();
}
break;
}
}
@AfterMethod
public synchronized void teardown() {
ThreadLocalDriver.getTLDriver().quit();
}
@AfterTest(alwaysRun = true)
public synchronized void stopAppiumServer(){
if(service.isRunning()) {
System.out.println("Stopping Appium Server");
service.stop();
}
else {
System.out.println("Appium Server Already Closed");
}
}
}
AppiumServiceBuilderUtil.java
public class AppiumServiceBuilderUtil {
public AppiumServiceBuilderUtil(){}
private static final ThreadLocal<AppiumDriverLocalService> tlService = new ThreadLocal<>();
public static synchronized void setTLService(AppiumDriverLocalService service) { tlService.set(service); }
public static synchronized AppiumDriverLocalService getTLService() {
return tlService.get();
}
public AppiumDriverLocalService buildAppiumService(){
String serverOS = Reporter.getCurrentTestResult().getTestContext().getCurrentXmlTest().getParameter("deviceOS");
AppiumServiceBuilder builder = new AppiumServiceBuilder();
/* Deprecated, Now uses default values
builder.withIPAddress("0.0.0.0");
builder.usingPort(4723);
*/
builder.usingAnyFreePort();
builder.withArgument(GeneralServerFlag.USE_PLUGINS, "relaxed-caps");
builder.withArgument(GeneralServerFlag.ALLOW_INSECURE, "chromedriver_autodownload");
builder.usingDriverExecutable(new File("/opt/homebrew/bin/node"));
builder.withLogFile(new File(String.format("logs/appium_server_log_%s.log", serverOS)));
setTLService(AppiumDriverLocalService.buildService(builder));
return getTLService();
}
}
DesiredCapabilitiesUtil.java
public class DesiredCapabilitiesUtil {
private static final ThreadLocal<DesiredCapabilities> tlCaps = new ThreadLocal<>();
static Properties props = new Properties();
public DesiredCapabilitiesUtil(){}
public static synchronized void setTlCaps(DesiredCapabilities caps){tlCaps.set(caps);}
public static synchronized DesiredCapabilities getTLCaps() {
return tlCaps.get();
}
public DesiredCapabilities getDesiredCapabilities(String deviceOS){
boolean localRun = Boolean.parseBoolean(System.getProperty("localRun", "false"));
String capFile;
if(localRun){
capFile = "local-decivecapabilities.properties";}
else {
capFile = "decivecapabilities.properties";}
try (InputStream inputStream = ClassLoader.getSystemResourceAsStream(capFile)){
props.load(inputStream);
} catch (Exception e) {e.printStackTrace();}
setTlCaps(new DesiredCapabilities());
tlCaps.get().setCapability("newCommandTimeout", 300);
switch (deviceOS) {
case "iOS":
tlCaps.get().setCapability("deviceName", props.getProperty("ios.capability.deviceName"));
tlCaps.get().setCapability("udid", props.getProperty("ios.capability.udid"));
tlCaps.get().setCapability("platformName", props.getProperty("ios.capability.platformName"));
tlCaps.get().setCapability("platformVersion", props.getProperty("ios.capability.platformVersion"));
tlCaps.get().setCapability("automationName", props.getProperty("ios.capability.automationName"));
tlCaps.get().setCapability("app", props.getProperty("ios.capability.app"));
tlCaps.get().setCapability("autoAcceptAlerts", true);
tlCaps.get().setCapability("includeSafariInWebviews", true);
tlCaps.get().setCapability("webviewConnectTimeout", 20000);
break;
case "Android":
tlCaps.get().setCapability("deviceName", props.getProperty("android.capability.deviceName"));
tlCaps.get().setCapability("udid", props.getProperty("android.capability.udid"));
tlCaps.get().setCapability("platformName", props.getProperty("android.capability.platformName"));
tlCaps.get().setCapability("platformVersion", props.getProperty("android.capability.platformVersion"));
tlCaps.get().setCapability("automationName", props.getProperty("android.capability.automationName"));
tlCaps.get().setCapability("unlockType", props.getProperty("android.capability.unlockType"));
tlCaps.get().setCapability("unlockKey", props.getProperty("android.capability.unlockKey"));
tlCaps.get().setCapability("app", props.getProperty("android.capability.app"));
tlCaps.get().setCapability("autoGrantPermissions", true);
break;
default:
throw new RuntimeException("No or invalid device OS given");
}
return getTLCaps();
}
}
ThreadLocalDriver.java
public class ThreadLocalDriver {
private static final ThreadLocal<AppiumDriver> tlDriver = new ThreadLocal<>();
public static synchronized void setTLDriver(AppiumDriver driver) { tlDriver.set(driver); }
public static synchronized AppiumDriver getTLDriver() {
return tlDriver.get();
}
}
testng.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Automation Test" parallel="tests" thread-count="2">
<test name="iOS">
<parameter name="deviceOS" value="iOS"/>
<parameter name="cucumber.filter.tags" value="(@ios or not @android) and not (@skip or @demo)"/>
<parameter name="cucumber.plugin" value="pretty, json:target/cucumber-reports_ios/test_results.json,
junit:target/cucumber-reports_ios/test_results.xml,
html:target/cucumber-reports_ios/test_results.html"/>
<classes>
<class name="runner.RunParallelTests"/>
</classes>
</test>
<test name="Android">
<parameter name="deviceOS" value="Android"/>
<parameter name="cucumber.filter.tags" value="(@android or not @ios) and not (@skip or @demo)"/>
<parameter name="cucumber.plugin" value="pretty, json:target/cucumber-reports_android/test_results.json,
junit:target/cucumber-reports_android/test_results.xml,
html:target/cucumber-reports_android/test_results.html"/>
<classes>
<class name="runner.RunParallelTests"/>
</classes>
</test>
</suite>
从那里开始,它是你的基本POM黄瓜升级。我确实在文件顶部初始化了所有页面对象,但我计划最终将它们移动到线程安全工厂类中。StepDefs.java
protected PageObject pageObject = new PageObject(ThreadLocalDriver.getTLDriver())
答:
我认为您应该收集这些错误发生时的日志,或者提供重现此错误的步骤,以便人们可以尝试找出在您的情况下发生此错误的原因。
评论