转载

Java控制Appium server start/stop

相信很多人都会遇到这种场景,在进行appium自动化的时候用Windows OS,不好实现后台运行,每次启动Appium server:

  • 使用Appium GUI版手动点击
  • 就是在cmd line 启动Appium 

如果要实现CI,使用Appium GUI是不可行的,因为如果在跑case的过程中Appium session无法创建必须重启Appium server,也无法自动获取相应的参数直接启动Appium

那么这个时候只能使用command line

PS:使用command line需要把Appium相关加入到环境变量

在path 添加

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

然后在command line验证一下

Java控制Appium server start/stop

如果出现这个,说明Appium使用默认参数启动成功

其实这个默认启动的是:C:/Program Files (x86)/Appium/node_modules/.bin/appium.bat

Java控制Appium server start/stop

使用默认的参数,如果想使用指定的ip和port log等内容需要加参数

比如使用:

 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

正文到此结束
Loading...