Java控制Appium server start/stop

相信不少人都會遇到這種場景,在進行appium自動化的時候用Windows OS,很差實現後臺運行,每次啓動Appium server:html

  • 使用Appium GUI版手動點擊
  • 就是在cmd line 啓動Appium 

若是要實現CI,使用Appium GUI是不可行的,由於若是在跑case的過程當中Appium session沒法建立必須重啓Appium server,也沒法自動獲取相應的參數直接啓動Appiumnode

那麼這個時候只能使用command lineapache

PS:使用command line須要把Appium相關加入到環境變量session

在path 添加app

;C:\Program Files (x86)\Appium\node_modules\.bin;

而後在command line驗證一下spa

若是出現這個,說明Appium使用默認參數啓動成功線程

其實這個默認啓動的是:C:\Program Files (x86)\Appium\node_modules\.bin\appium.batdebug

使用默認的參數,若是想使用指定的ip和port log等內容須要加參數code

好比使用: server

C:\Users\Test>appium -a 127.0.0.1 -p 1235
info: Welcome to Appium v1.4.16 (REV ae6877eff263066b26328d457bd285c0cc62430d)
info: Appium REST http interface listener started on 127.0.0.1:1235
info: [debug] Non-default server args: {"address":"127.0.0.1","port":1235}
info: Console LogLevel: debug

具體參數這裏再也不詳解,可使用appium --help 


那麼好了,直接使用Java調用這個command的就行了

因而寫了就這樣:

 public void excuteCMD(String comand)
    {
        Runtime rt = Runtime.getRuntime();
        RuntimeExec rte = new RuntimeExec();
        StreamWrapper error, output;

        try
        {
            Process proc = rt.exec(comand);
            error = rte.getStreamWrapper(proc.getErrorStream(), "ERROR");
            output = rte.getStreamWrapper(proc.getInputStream(), "OUTPUT");
            BufferedReader stdInput = new BufferedReader(new InputStreamReader(proc.getInputStream()));
            String s;
            while ((s = stdInput.readLine()) != null)
            {
                System.out.println(s);
                if (s.contains("Appium REST http"))
                {
                    System.out.println("STARTED!");
                }
            }

            error.start();
            output.start();
            error.join(3000);
            output.join(3000);
            System.out.println("Output: " + output.message + "\nError: " + error.message);
        } catch (IOException e)
        {
            e.printStackTrace();
        } catch (InterruptedException e)
        {
            e.printStackTrace();
        }
    }

使用Java runtime class

傳入相應的command, 而後執行並把輸入顯示出來

而後發現這樣作行不通, 由於無法執行下面的code

 

查了相關資料才知道這個叫線程阻塞

因而乎只能找到一種非線程阻塞的方法

 


 

這個時候找到一個commons-exec的project能給解決問題

根據官方文檔,若是使用非阻塞執行,能夠這樣作:

  • 首先建立一個非阻塞的handler DefaultExecuteResultHandler,這個是專門用來處理非阻塞
  • 在建立一個watchdog用來監控輸出,設置timeout時間60s
  • 建立一個執行器設置退出代碼爲1,表明執行成功

注意,這裏必須設置一個waitfor time,若是沒有設置會報錯

  resultHandler.waitFor(5000);
public static String APPIUMSERVERSTART = "C:\\Program Files (x86)\\Appium\\node_modules\\.bin\\appium.cmd";

    public static void startServer() throws IOException, InterruptedException
    {
     
        startServer("4723");
        // RuntimeExec appiumObj = new RuntimeExec();
        // appiumObj.excuteCMD(APPIUMSERVERSTART);
        DefaultExecuteResultHandler resultHandler = new DefaultExecuteResultHandler();
        CommandLine commandLine = CommandLine.parse(APPIUMSERVERSTART);
        ExecuteWatchdog dog = new ExecuteWatchdog(60 * 1000);
        Executor executor = new DefaultExecutor();
        executor.setExitValue(1);
        executor.setWatchdog(dog);
        executor.execute(commandLine, resultHandler);
        resultHandler.waitFor(5000);
        System.out.println("Appium server start");
    }

 

以上code實現的是使用默認的port啓動Appium server ,若是遇到Appium端口被佔用,啓動失敗怎麼辦?

個人策略是先殺掉因此佔用這個端口的進程:

能夠嘗試使用command line

cmd /c echo off & FOR /F "usebackq tokens=5" %a in (`netstat -nao ^| findstr /R /C:"4723"`) do (FOR /F "usebackq" %b in (`TASKLIST /FI "PID eq %a" ^| findstr /I node.exe`) do taskkill /F /PID %a)

    /**
     * @author Young
     * @param appiumServicePort
     * @throws ExecuteException
     * @throws IOException
     */
    public static void stopAppiumServer(String appiumServicePort) throws ExecuteException, IOException
    {
        ExectorUtils.runWithWatchDog("cmd /c echo off & FOR /F \"usebackq tokens=5\" %a in"
                + " (`netstat -nao ^| findstr /R /C:\"" + appiumServicePort + "\"`) do (FOR /F \"usebackq\" %b in"
                + " (`TASKLIST /FI \"PID eq %a\" ^| findstr /I node.exe`) do taskkill /F /PID %a)");
    }

 

 

這樣就能夠在每一個test case啓動相應的Appium server而且給出指定的參數。

 


 

相關資料:http://commons.apache.org/proper/commons-exec/tutorial.html

相關文章
相關標籤/搜索