我尝试使用多个设备设置框架自动化设置,每个设备根据连接的设备数量创建一个 Appium 服务器。我能够创建一个 Appium 服务器并将其分配给每个设备,但是当它启动并首先显示为每个设备编写的功能的正确形式时。但是,当我开始运行测试时,第二台服务器的会话被覆盖并连接到第一台设备,结果,第二台服务器的第二台设备上没有运行任何测试。
有没有一种功能可以让 Appium 服务器坚持分配给他们的设备并且永远不会被覆盖?
以下是会话被另一台设备覆盖时的一些日志:
[Appium] Welcome to Appium v1.8.1
[Appium] Non-default server args:
[Appium] address: 127.0.0.1
[Appium] port: 5001
[Appium] defaultCapabilities: {
[Appium] noReset: false
[Appium] }
[Appium] Default capabilities, which will be added to each request unless overridden by desired capabilities:
[Appium] noReset: false
[Appium] Appium REST http interface listener started on 127.0.0.1:5001
[HTTP] --> POST /wd/hub/session
[HTTP] {"desiredCapabilities":{"browserName":"Chrome","deviceId":"192.168.174.101:5555\t","deviceName":"device2","newCommandTimeout":"4000","noReset":false,"platformName":"Android"},"capabilities":{"desiredCapabilities":{"browserName":"Chrome","deviceId":"192.168.174.101:5555\t","deviceName":"device2","newCommandTimeout":"4000","noReset":false,"platformName":"Android"},"firstMatch":[{"browserName":"Chrome","platformName":"android"}]}}
[debug] [MJSONWP] Calling AppiumDriver.createSession() with args: [{"browserName":"Chrome","deviceId":"192.168.174.101:5555\t","deviceName":"device2","newCommandTimeout":"4000","noReset":false,"platformName":"Android"},null,{"desiredCapabilities":{"browserName":"Chrome","deviceId":"192.168.174.101:5555\t","deviceName":"device2","newCommandTimeout":"4000","noReset":false,"platformName":"Android"},"firstMatch":[{"browserName":"Chrome","platformName":"android"}]}]
[debug] [BaseDriver] Event 'newSessionRequested' logged at 1537146899868 (18:14:59 GMT-0700 (Pacific Daylight Time))
[BaseDriver] The capabilities ["noReset"] are not standard capabilities and should have an extension prefix
[BaseDriver] Boolean capability passed in as string. Functionality may be compromised.
[Appium] Could not parse W3C capabilities: 'deviceName' can't be blank. Falling back to JSONWP protocol.
[Appium] The following capabilities were provided in the JSONWP desired capabilities that are missing in W3C capabilities: ["noReset","browserName","deviceId","deviceName","newCommandTimeout","platformName"]. Falling back to JSONWP protocol.
[Appium] Creating new AndroidDriver (v2.7.0) session
[Appium] Capabilities:
[Appium] noReset: false
[Appium] browserName: Chrome
[Appium] deviceId: 192.168.174.101:5555
[Appium] deviceName: device2
[Appium] newCommandTimeout: 4000
[Appium] platformName: Android
[debug] [BaseDriver] Creating session with MJSONWP desired capabilities: {"noReset":false,"browserNa...
[BaseDriver] Capability 'newCommandTimeout' changed from string ('4000') to integer (4000). This may cause unexpected behavior
[BaseDriver] The following capabilities were provided, but are not recognized by appium: deviceId.
[BaseDriver] Session created with session id: 68b1e594-54d4-4241-befc-a6b8beefe2f9
[debug] [AndroidDriver] Getting Java version
[AndroidDriver] Java version is: 1.8.0_181
[AndroidDriver] We're going to run a Chrome-based session
[AndroidDriver] Chrome-type package and activity are com.android.chrome and com.google.android.apps.chrome.Main
[ADB] Checking whether adb is present
[ADB] Found 3 'build-tools' folders under 'C:\Users\Rigat\AppData\Local\Android\Sdk' (newest first):
[ADB] C:/Users/Rigat/AppData/Local/Android/Sdk/build-tools/28.0.0-rc1
[ADB] C:/Users/Rigat/AppData/Local/Android/Sdk/build-tools/27.0.3
[ADB] C:/Users/Rigat/AppData/Local/Android/Sdk/build-tools/26.0.2
[ADB] Using adb.exe from C:\Users\Rigat\AppData\Local\Android\Sdk\platform-tools\adb.exe
[AndroidDriver] Retrieving device list
[debug] [ADB] Trying to find a connected android device
[debug] [ADB] Getting connected devices...
[debug] [ADB] 2 device(s) connected
[AndroidDriver] Using device: 192.168.174.102:5555
[debug] [ADB] Setting device id to 192.168.174.102:5555
[AndroidDriver] App file was not listed, instead we're going to run com.android.chrome directly on the device
[debug] [AndroidDriver] Checking whether package is present on the device
[debug] [ADB] Running 'C:\Users\Rigat\AppData\Local\Android\Sdk\platform-tools\adb.exe -P 5037 -s 192.168.174.102\:5555 shell pm list packages com.android.chrome'
[AndroidDriver] Starting Android session
[debug] [ADB] Running 'C:\Users\Rigat\AppData\Local\Android\Sdk\platform-tools\adb.exe -P 5037 -s 192.168.174.102\:5555 wait-for-device'
[debug] [ADB] Running 'C:\Users\Rigat\AppData\Local\Android\Sdk\platform-tools\adb.exe -P 5037 -s 192.168.174.102\:5555 shell echo ping'
[debug] [AndroidDriver] Pushing settings apk to device...
[debug] [ADB] Getting install status for io.appium.settings
[debug] [ADB] Running 'C:\Users\Rigat\AppData\Local\Android\Sdk\platform-tools\adb.exe -P 5037 -s 192.168.174.102\:5555 shell pm list packages io.appium.settings'
以下是设置设备和服务器时的代码:
public PageObject pageObject = null;
public AppiumDriverSetup createDrivers = new AppiumDriverSetup();
@BeforeClass(alwaysRun=true)
public void setupDrivers() throws IOException {
createDrivers.makeList();
for(AppiumDriver<MobileElement> driver : createDrivers.getActiveList()){
this.driver = driver;
TLDriverFactory.setTLDriver(driver);
System.out.println("Calling for driver: " + driver.getCapabilities());
wait = new WebDriverWait(TLDriverFactory.getTLDriver(), 10);
testActivation();
}
}
@Test
public void testActivation() {
assertTrue(driver != null);
pageObject = new PageObject(TLDriverFactory.getTLDriver());
pageObject.driver.get("https://www.google.com");
}
public class AppiumDriverSetup {
enum Devices {
ANDROID, IOS;
}
public static int deviceNum = 0;
public AppiumDriver<MobileElement> driver;
private List<Object> newDevice = new ArrayList<Object>();
private static List<AppiumDriver<MobileElement>> activeList = Collections.synchronizedList(new ArrayList<AppiumDriver<MobileElement>>());
AppOrBrowser determinePlatType = new AppOrBrowser();
ActiveAppiumPorts activePorts = new ActiveAppiumPorts();
public void makeList () throws IOException {
Runtime rt = Runtime.getRuntime();
Process p = rt.exec("adb devices");
BufferedReader output = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line ="";
while ((line = output.readLine()) != null) {
if(StringUtils.isEmpty(line) || line.startsWith("List of devices attached")) {
continue;
}
System.out.println(line);
String [] serialNum = line.replace(" ", "").split("device");
newDevice.add(Devices.ANDROID);
newDevice.add(serialNum[0]);
driver = setCaps((Devices)newDevice.get(0), (String)newDevice.get(1));
activeList.add(driver);
newDevice.clear();
}
//Implement the IOS Process
}
private AppiumDriver<MobileElement> setCaps(Devices d, String udid) throws MalformedURLException{
AppiumDriver<MobileElement> driver = null;
DesiredCapabilities cap = new DesiredCapabilities();
String deviceName = "device"+ ++deviceNum;
cap.setCapability(MobileCapabilityType.DEVICE_NAME, deviceName);
if(d == Devices.ANDROID) {
cap.setCapability(MobileCapabilityType.PLATFORM_NAME, "Android");
}
if(d == Devices.IOS) {
cap.setCapability(MobileCapabilityType.PLATFORM_NAME, "IOS");
}
cap.setCapability("deviceId", udid);
cap.setCapability(MobileCapabilityType.NEW_COMMAND_TIMEOUT, "4000");
cap.setCapability("noReset", false);
cap = determinePlatType.determinePlat(cap);
//Generate AppiumPorts Class and retrieve generated port number.
activePorts.generateServer();
System.out.println("Argument to driver object : " + activePorts.getAppiumURL() + "\n");
switch (d) {
case ANDROID:
driver = new AndroidDriver<MobileElement>(new URL(activePorts.getAppiumURL()), cap);
break;
case IOS:
driver = new IOSDriver<MobileElement>(new URL(activePorts.getAppiumURL()), cap);
break;
}
activePorts.increasePortNum();
return driver;
}
public List<AppiumDriver<MobileElement>> getActiveList(){
return activeList;
}
public void tearDown() {
driver.quit();
}
}
public class ActiveAppiumPorts {
private int portNum = 5000;
private String appiumPort = "500" + portNum;
private String serverIp = "127.0.0.1";
public String getAppiumURL() {
String serverURL = "http://" + serverIp + ":" + portNum + "/wd/hub";
System.out.println(serverURL);
return serverURL;
}
public void increasePortNum() {
portNum++;
System.out.println("Next Port will be: " + portNum);
}
public String getPort() {
return ""+portNum;
}
public void generateServer() {
Runtime runtime = Runtime.getRuntime();
try {
runtime.exec("cmd.exe /c start cmd.exe /k \"appium -a " + serverIp + " -p " + portNum +
"--session-override -dc \" {\"\"noReset\"\": \"\"false\"\"}\"\"");
Thread.sleep(20000);
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException r) {
r.printStackTrace();
}
}
public void stopServer() {
Runtime runtime = Runtime.getRuntime();
try {
runtime.exec("taskkill /F /IM node.exe");
runtime.exec("taskkill /F /IM cmd.exe");
} catch (IOException e) {
e.printStackTrace();
}
}
}
这是我运行测试时为驱动程序显示的日志:
Calling for driver: Capabilities {browserName: Chrome, databaseEnabled: false, desired: {browserName: Chrome, deviceId: 192.168.174.102:5555 , deviceName: device1, newCommandTimeout: 4000, noReset: false, platformName: Android}, deviceId: 192.168.174.102:5555 , deviceManufacturer: Genymotion, deviceModel: Samsung Galaxy S7 - 6.0.0 -..., deviceName: 192.168.174.102:5555, deviceScreenSize: 1440x2560, deviceUDID: 192.168.174.102:5555, javascriptEnabled: true, locationContextEnabled: false, networkConnectionEnabled: true, newCommandTimeout: 4000, noReset: false, platform: LINUX, platformName: LINUX, platformVersion: 6.0, takesScreenshot: true, warnings: {}, webStorageEnabled: false}
Calling for driver: Capabilities {browserName: Chrome, databaseEnabled: false, desired: {browserName: Chrome, deviceId: 192.168.174.101:5555 , deviceName: device2, newCommandTimeout: 4000, noReset: false, platformName: Android}, deviceId: 192.168.174.101:5555 , deviceManufacturer: Genymotion, deviceModel: Samsung Galaxy S7 - 6.0.0 -..., deviceName: 192.168.174.102:5555, deviceScreenSize: 1440x2560, deviceUDID: 192.168.174.102:5555, javascriptEnabled: true, locationContextEnabled: false, networkConnectionEnabled: true, newCommandTimeout: 4000, noReset: false, platform: LINUX, platformName: LINUX, platformVersion: 6.0, takesScreenshot: true, warnings: {}, webStorageEnabled: false}