最近一直在学习appium的自动化,想在mac电脑上跑批量执行。之前我也分享了在windos系统上批量启动appium的方法:https://www.cnblogs.com/boqinyaxin/p/13330643.html,有想了解的可以点击开看一下,还有启动参数的解释,不明白的可以看这个 https://www.cnblogs.com/boqinyaxin/p/13434774.html。
在mac上想批量启动设备执行脚本需要启动对应的端口号和设备绑定,可以手动启动多个终端来开多个appium,也可以在程序里批量启动。
手动启动多个终端来开多个appium的方法如下:
打开多个终端,在打开的每个终端上输入像下面的命令,根据自己的设备该响应参数:
appium -p 4745 -bp 4746 --session-override --chromedriver-port 9537 -U 5769b4719905 > /testNglogs/4745.txt
启动好后,在我创建好的日志目录下面就生成了两个日志文件4745.txt 和4747.txt,这两个日志文件里会打印启动的appium信息
上面介绍了怎么手动启动多个appium,下面来介绍程序内启动。
在执行脚本的过程中,人为干预去启动appium还是很不方便的,所以我写了一段代码去调用终端启动appium命令。
public class AppiumServer {
/**
* 提供给mac电脑启动终端执行命令的方法
* @param cmd
*/
private void runCommandBuilde(String cmd){
try {
ProcessBuilder pb = new ProcessBuilder("/bin/bash","-c",cmd);
Process p = pb.start();
new Thread(new StreamGobbler(p.getInputStream(), "OUT")).start();
new Thread(new StreamGobbler(p.getErrorStream(), "ERR")).start();
p.getOutputStream().close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
在写这个方法的时候runCommandBuilde,要分线程去输出数据,关闭输出流,不然程序就会卡住不动,原因是进程会一直阻塞等待输出
流处理类
public class StreamGobbler extends Thread {
private final static Logger logger = LoggerFactory.getLogger(StreamGobbler.class);
private InputStream is;
private String type;
private OutputStream os;
/**
* 构造函数
*
* @param is
* @param type
*/
public StreamGobbler(InputStream is, String type) {
this.is = is;
this.type = type;
}
/**
* 构造函数
*
* @param is
* @param type
* @param redirect 输出文件目录
*/
public StreamGobbler(InputStream is, String type, OutputStream redirect) {
this.is = is;
this.type = type;
this.os = redirect;
}
@Override
public void run() {
StringBuilder buffer = new StringBuilder();
try {
PrintWriter pw = null;
if (os != null) {
pw = new PrintWriter(os);
}
String sysOS = System.getProperty("os.name");
InputStreamReader isr;
if(sysOS.contains("Windows")){
//要把bat文件编码格式改为GB2312,然后读取流的时候也用GB2312,不然会乱码(因为windows的编码基本是GB2312或者GBK)
isr = new InputStreamReader(is, "GB2312");
}else{
isr = new InputStreamReader(is,"UTF-8");
}
BufferedReader br = new BufferedReader(isr);
String line = null;
while ((line = br.readLine()) != null) {
if (pw != null) {
pw.println(line);
}
logger.info(type + ">" + line);
}
if (pw != null) {
pw.flush();
}
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
}
调用启动方法的时候传递一下参数就可以了,
省略我其他地方代码就写调用的地方和传参。
//需要写mac的地址
//appiumCmdPath = "/usr/local/bin/appium";这是我mac电脑上appium脚本的路径
appiumCmdPath = "appium";
command = appiumCmdPath+" -p " + port+" -bp "+bport+" --session-override --chromedriver-port "+chromeport+" -U "+uuid+" > /testNglogs/"+port+".txt";
runCommandBuilde(command);
程序执行的时候,调用上面的方法和手动启动多个终端的效果一样的。一样正常生成日志输出文档,程序在运行过程中,appium的运行日志也会打印到指定的日志文件里。
我的代码执行的还不是很完善,后续会写一下我更多的改进方法,在写这个类的过程中,参考了下面几个地址,看一下对理解有帮助。
如何从java程序在终端上运行命令?
http://www.cocoachina.com/articles/53244
如何获取刚在java程序中启动的进程的PID
https://zhidao.baidu.com/question/1695685649416921508.html
Java 执行 Mac(Unix) 脚本命令
http://yang3wei.github.io/blog/2013/02/05/java-zhi-xing-mac-unix-jiao-ben-ming-ling/
怎么通过java去调用并执行shell脚本以及问题总结
https://developer.aliyun.com/article/2362
Java进程Runtime、Process、ProcessBuilder调用外部程序
https://blog.csdn.net/c315838651/article/details/72085739?utm_medium=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param
ProcessBuilder 用法详解
https://blog.csdn.net/shadow_zed/article/details/93545843