2016-07-19 52 views
0

我無法在具有多個移動設備的Android平臺上並行自動執行測試。Appium並行執行不同的服務器

如果我將2個設備連接到我的系統並提供移動設備名稱和版本等功能,則它正在通過ADB首先識別的設備中執行。

如果嘗試使用不同的端口啓動appium服務器,

new AppiumServiceBuilder().usingAnyFreePort() I am getting Null pointer Exception. 
[36minfo[39m: Appium REST http interface listener started on 0.0.0.0:2583 
[36minfo[39m: [debug] Non-default server args: {"port":2583} 

1)如何與AppiumServiceBuilder()

2)如何限制appium執行上覆蓋會話提供有能力的設備,甚至連接2個或更多設備。

我的代碼:

public class ApiumMain { 
    public static void main(String[] args) { 
     new Thread(new Device_Thread("4897bb00", "6.0.1")).start(); 
     // new Thread(new Device_Thread("TA64301YVY", "5.0.1")).start(); 
    } 
} 
public class Device_Thread extends ApiumMain implements Runnable { 

    public String mobileDeviceName; 
    public String androidVersion; 

    public Device_Thread(String mobile, String version) { 
     mobileDeviceName = mobile; 
     androidVersion = version; 
    } 

    @Override 
    public void run() { 
     String hsotMachineIP = "127.0.0.1"; 
     Integer seleniumProt = 4723; /*Default {"port":4723}*/ 

     String nodeJSExecutable = "C:\\Program Files (x86)\\Appium\\node.exe"; 
     String appiumJS = "C:\\Program Files (x86)\\Appium\\node_modules\\appium\\bin\\appium.js"; 
     Integer nodeJSPort = (int)(Math.random() * 8000) + 1000; 

     startAppium(nodeJSExecutable, nodeJSPort, appiumJS, mobileDeviceName, androidVersion, hsotMachineIP, seleniumProt); 
    } 

    public void startAppium(String nodeJSExecutable, int nodeJSPort, String appiumJS, 
      String mobileDeviceName, String androidVersion, String hsotMachineIP, int seleniumProt) { 

     RemoteWebDriver driver = null; 
     String appURL = "http://www.w3schools.com/"; 

     // http://appium.io/slate/en/master/?java#appium-server-capabilities 
     DesiredCapabilities capabilities = new DesiredCapabilities(); 
     capabilities.setCapability("automationName", "Appium"); 
     capabilities.setCapability("platformName",  "Android"); 
     capabilities.setCapability("platformVersion", androidVersion); 
     capabilities.setCapability("deviceName",  mobileDeviceName); 
     capabilities.setCapability("app",    "chrome"); 
     capabilities.setCapability("browserName",  "chrome"); 
     capabilities.setCapability("newCommandTimeout", "0"); 
     // ANDROID ONLY 
     /*capabilities.setCapability("appActivity",  "com.android"); 
     capabilities.setCapability("appPackage",  ".ApiumMain"); 
     */ 

     // Appium servers are nothing but the Node.js server 
     AppiumDriverLocalService service = AppiumDriverLocalService.buildService(
        new AppiumServiceBuilder() 
        .usingDriverExecutable(new File(nodeJSExecutable)) 
        .withAppiumJS(new File(appiumJS)) 
       ); 

     service.start();   
     System.out.println("Device : " + mobileDeviceName); 

     try { 
      String url = String.format("http://%s:%d/wd/hub", hsotMachineIP, seleniumProt); 
      System.out.println(" Server Address : " + url); 
      driver = new RemoteWebDriver(new URL(url), capabilities); 

      driver.get(appURL); 
      browserActions(driver, appURL); 

     }catch (MalformedURLException e) { 
      e.printStackTrace(); 
     } finally { 
      driver.quit(); 
      service.stop(); 
     } 
    } 
    private void browserActions(RemoteWebDriver driver, String appURL) { 

     try { 
      WebElement ele = driver.findElementByXPath("//body/div[4]/div[1]/div[1]/a[1]"); 
      ele.click(); 

      WebElement ele2 = driver.findElementByXPath("//*[@id='topnav']/div[1]/div[1]/a[2]"); 
      ele2.click(); 

      System.in.read(); 
      System.in.read(); 
     } catch (ElementNotVisibleException logMsg){ 
     } catch (IOException e) { 
     } 
    } 
} 

Appium setup對於Windows: 已安裝Android SDK,Appium [Server & java-client],添加ADT pugin到Eclipse IDE和硒 - 服務器standalone

設置環境變量:

AVA_HOME~C:\Program Files (x86)\Java\jdk1.8.0_66 
ANDROID_HOME~D:\Android\sdk 
Path~D:\Android\sdk;D:\Android\sdk\platform-tools - ADB Debugger 

回答

0

運行多個Appiumsessions具有不同Server flags並行的Android測試

Appium是自動化天然的,移動網絡的開放源碼工具,和混合應用在IOS和Android平臺上。圍繞硒客戶端庫

Appium client libraries渦卷與添加到控制移動設備

  • Client一些額外的命令:在其上WebDriver [HTTP客戶端] API被用於通信的機與服務器通過命令。 Appium Client執行「Mobile JSONWP」擴展「JSONWP」。 Mobile JSONWP用於本地和混合移動應用程序的自動化,JSONWP用於自動化網絡瀏覽器應用程序。

Commands:與本說明書中所定義的方法和模板每個HTTP請求表示單個命令,並且因此每個命令產生單個HTTP響應。客戶端通過JSON使用所需功能啓動與服務器的會話。基於瀏覽器會話ID和Selenium remoteServerAddress,通過Http Rest API進行通信。 HTTP客戶端的

硒來源:

HttpClient.Factory httpClientFactory = new ApacheHttpClient.Factory(); 
HttpClient client = httpClientFactory.createClient(remoteServerAddress); 

HttpRequest httpRequest = commandCodec.encode(command); 
HttpResponse httpResponse = client.execute(httpRequest, true); 
Response response = responseCodec.decode(httpResponse); 
  • Server開始任何手機測試之前,你必須開始喜歡RemoteWebDriver & Appium服務器|的NodeJS。 AppiumServer - 寫在Node.js的 SeleniumRCServer REST API - Selenium服務器從測試程序使用HTTP GET/POST請求,解釋接收Selenium命令並執行這些命令,並報告結果給你的程序。

夫婦連接Android設備到系統並運行以下命令adb shell

D:\Yash>adb devices 
List of devices attached 
TA64301YVY  device 
4897bb00  device 

D:\Yash>adb -s TA64301YVY shell getprop ro.build.version.release 
5.1  

D:\Yash>adb -s TA64301YVY shell getprop > D:\Yash\cmdOUT.txt 
     +----------------------------+------------+--------------+ 
     |[net.bt.name]:    | [Android] | [Android] | 
     |[ro.boot.serialno]:   | [4897bb00] | [TA64301YVY] | 
     |[ro.product.brand]:   | [samsung] | [motorola] | 
     |[ro.product.model]:   | [SM-G900F] | [XT1052]  | 
     |[ro.build.version.release]: | [6.0.1] | [5.1]  | 
     +----------------------------+------------+--------------+ 

Q1 - 答:要使用AppiumServiceBuilder使用這種說法 「GeneralServerFlag SESSION_OVERRIDE」 覆蓋會話。如果我們沒有提供UDID(或)RemoteAddress,則驅動程序將連接到由ADB檢測到的第一個設備。如果我們想限制appium在連接的設備列表中連接特定的已命名物理設備,請使用UDID唯一設備標識符。

JAVA Parallel Android Testsautomate mobile web apps [Java的客戶機 - 4.1.1.jar]:

  • nodeJSExec«[C:\程序文件(x86)\ Appium \ node.exe]
  • nodeJSArgs«[C:\ Program Files(x86)\ Appium \ node_modules \ appium \ bin \ appium.js,--port,1750, - 地址,127.0.0.1,--log,D:\ Yash \ MyAppiumConsole_4897bb00.txt,--chromedriver-port,7115,--bootstrap-port,7119, - 激活覆蓋]

public void startAppium(String nodeJSExecutable, int nodeJSPort, String appiumJS, String mobileDeviceName, 
    String androidVersion, String hsotMachineIP) { 
    RemoteWebDriver driver = null; 
    String appURL = "http://www.w3schools.com/"; 

    File logFile = new File("D:/Yash/MyAppiumConsole_"+mobileDeviceName+".txt"); 
    File javaConsole = new File("D:/Yash/MyJavaConsole_"+mobileDeviceName+".txt"); 
    systemConsole2File(javaConsole); 

    /*The hub only reads browserName, version, platform and applicationName. 
    The other capabilities (deviceName, platformVersion, platformName, ...) are Appium capabilities, not used by the hub.*/  

    // Proxying straight through to Chromedriver 
    DesiredCapabilities capabilities = DesiredCapabilities.android(); 
    /* Appium - io.appium.java_client.remote */ 
    capabilities.setCapability(MobileCapabilityType.AUTOMATION_NAME, "Appium"); 
    capabilities.setCapability(MobileCapabilityType.PLATFORM_NAME,  "Android"); 
    capabilities.setCapability(MobileCapabilityType.PLATFORM_VERSION, androidVersion); 
    capabilities.setCapability(MobileCapabilityType.DEVICE_NAME,  mobileDeviceName); 
    capabilities.setCapability(MobileCapabilityType.BROWSER_NAME,  "chrome"); // "Browser" 
    capabilities.setCapability(MobileCapabilityType.UDID,    mobileDeviceName); 

    /* Selenium - org.openqa.selenium.remote */ 
    capabilities.setCapability(CapabilityType.TAKES_SCREENSHOT, "true");   

    // Appium servers are nothing but the Node.js server   
    AppiumDriverLocalService service = AppiumDriverLocalService.buildService(
       new AppiumServiceBuilder() 
       .withAppiumJS(new File(appiumJS)) 
       .usingDriverExecutable(new File(nodeJSExecutable)) 
       .usingPort(nodeJSPort) 
       .withIPAddress(hsotMachineIP) 
       .withArgument(GeneralServerFlag.SESSION_OVERRIDE) 
       .withArgument(AndroidServerFlag.BOOTSTRAP_PORT_NUMBER, nextFreePort().toString()) 
       .withArgument(AndroidServerFlag.CHROME_DRIVER_PORT, nextFreePort().toString()) 
       .withLogFile(logFile) 
      );  
    service.start(); 

    System.out.println(" Appium Server Address [Local]: " + service.getUrl()); 
    driver = new RemoteWebDriver(service.getUrl(), capabilities);  
    ... 
} 
public static final int HIGHEST_PORT = 65535; 
public static final int LEAST_PORT = 1024; 
public static Integer nextFreePort() { 
    Integer port = (int)(Math.random() * 8000) + LEAST_PORT; 
    while (true) { 
     try (ServerSocket endpoint = new ServerSocket(port)) { 
      System.out.println("Local Port on which this socket is listening :"+port); 
      return port; 
     } catch (IOException e) { 
      port = ThreadLocalRandom.current().nextInt(); 
     } 
    } 
} 
public static void systemConsole2File(File logFile) { 
    try (FileOutputStream fos = new FileOutputStream(logFile); 
      PrintStream system_console = new PrintStream(fos) 
     ) { 
     System.setOut(system_console); // output stream. 
     System.setErr(system_console); // error output stream. 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
} 

Appium日誌與endpoints從節點,其中被執行的腳本:

<?-- APPIUM_NODEJS_LISTENING_PORT = 4723 SERVERS <--port, --callback-port 4723> 
    Mobile « http://127.0.0.1:4723/wd/hub 
    Desktop « http://localhost:4444/wd/hub 
--> 
[36minfo[39m: Appium REST http interface listener started on 127.0.0.1:1750 
[36minfo[39m: [debug] Non-default server args: 
{ 
    "address":"127.0.0.1", 
    "port":1750, 
    "bootstrapPort":7119, 
    "sessionOverride":true, 
    "log":"D:\\Yash\\MyConsole_TA64301YVY.txt", 
    "chromeDriverPort":7115 
} 


<?-- LIST OF CONNECTED DEVICES [UDID] 
Unique device identifier of the connected physical device 
To connect specific named device in the list of connected devices use UDID 
--> 
[36minfo[39m: [debug] Trying to find a connected android device 
[36minfo[39m: [debug] Getting connected devices... 
[36minfo[39m: [debug] executing cmd: D:\Android\sdk\platform-tools\adb.exe devices 
[36minfo[39m: [debug] 2 device(s) connected 
[36minfo[39m: Found device TA64301YVY 
[36minfo[39m: [debug] Setting device id to TA64301YVY 

<?-- 
BOOTSTRAP = 4724 Socket tcp port to use on device to talk to Appium 
     « Forwarding system:4724 to device:4724 appium bootstrap to device 
--> 
[36minfo[39m: [debug] Forwarding system:7119 to device:4724 
[36minfo[39m: [debug] executing cmd: D:\Android\sdk\platform-tools\adb.exe -s TA64301YVY forward tcp:7119 tcp:4724 
[36minfo[39m: [debug] Pushing appium bootstrap to device... 


<?-- 
Chrome debugger server to connect to, in the form of <hostname/ip:port> 
CHROME_DRIVER = 9515 Port upon which ChromeDriver will run 
--> 
[36minfo[39m: Chromedriver: Spawning chromedriver with: C:\Program Files (x86)\Appium\node_modules\appium\node_modules\appium-chromedriver\chromedriver\win\chromedriver.exe --url-base=wd/hub --port=7115 
[36minfo[39m: Chromedriver: [STDOUT] Starting ChromeDriver 2.18.343845 (73dd713ba7fbfb73cbb514e62641d8c96a94682a) on port 7115 

APPLICATION URL: 
[36minfo[39m: JSONWP Proxy: Proxying [POST /wd/hub/session/SESSION-ID/url] to [POST http://127.0.0.1:7115/wd/hub/session/SESSION-ID/url] with body: {"url":"http://www.w3schools.com/"} 
[36minfo[39m: JSONWP Proxy: Got response with status 200: {"sessionId":"SESSION-ID","status":0,"value":null} 

WEB ELEMENT: 
[36minfo[39m: JSONWP Proxy: Proxying [POST /wd/hub/session/SESSION-ID/element] to [POST http://127.0.0.1:7115/wd/hub/session/SESSION-ID/element] with body: {"using":"xpath","value":"//body/div[4]/div[1]/div[1]/a[1]"} 
[36minfo[39m: JSONWP Proxy: Got response with status 200: {"sessionId":"SESSION-ID","status":0,"value":{"ELEMENT":"0.39628730167672455-1"}} 

WEB ELEMENT & ACTION: 
[36minfo[39m: JSONWP Proxy: Proxying [POST /wd/hub/session/SESSION-ID/element/0.39628730167672455-1/click] to [POST http://127.0.0.1:7115/wd/hub/session/SESSION-ID/element/0.39628730167672455-1/click] with body: {"id":"0.39628730167672455-1"} 
[36minfo[39m: JSONWP Proxy: Got response with status 200: {"sessionId":"SESSION-ID","status":0,"value":null}