相信不少人都会遇到这种场景,在进行appium自动化的时候用Windows OS,很差实现后台运行,每次启动Appium server:html
若是要实现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能给解决问题
根据官方文档,若是使用非阻塞执行,能够这样作:
注意,这里必须设置一个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