相信很多人都会遇到这种场景,在进行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)Appiumnode_modules.bin;
复制代码然后在command line验证一下 如果出现这个,说明Appium使用默认参数启动成功 其实这个默认启动的是:C:Program Files (x86)Appiumnode_modules.binappium.bat 使用默认的参数,如果想使用指定的ip和port log等内容需要加参数 比如使用: - C:UsersTest>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,如果没有设置会报错 - <strong> resultHandler.waitFor(5000);</strong>
复制代码- 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 来自: http://www.cnblogs.com/tobecrazy/p/5118170.html |