说明

非真的并行,多个设备初始化,加了等待时间,没有真的同时并发,两台设备可以执行相同的 case
下面有说 多台设备(3 台 或者 4 台)同时执行 Xcodebuild 指令会有很多报错,有时不能全部初始化成功,原因未知

### 8900 端口错误
macaca-ios 的代码里面,多台初始化时候每次全部指定 8900 端口,造成无法并行执行。查看源代码,发现判断端口是否占用的脚本实际上不生效
this.proxyPort = yield detect(this.proxyPort)
源码这个原本的意图是判断端口时候占用,占用时候分配一个新端口,实际上使用的方式不对,导致判断无效,而且 xctest-client 默认使用 8900 端口,所以不管多少台 ios 真机设备,初始化都会是 8900,导致错误。

我改了初始化 ios driver 的逻辑,支持传入 proxy 端口,指定端口就不会出现上面的问题
需要替换 macaca-ios 默认安装包里的文件
https://github.com/baozhida/macaca-ios/blob/master/lib/macaca-ios.js

2016.3.7 更新

官方的版本已经合并我提交的代码,直接更新即可,不需要手动替换 macaca-ios.js

此脚本可以指定 proxyPort,和 reuse 的使用方式一样,传数字即可,见下面的例子。

初始化日志

第一台设备
>> macaca-ios.js:153:12 [master] pid:22732 Trying to start wda server...
>> xctest-client start with port: 8900
>> xctest-client.js:234:14 [master] pid:22732 xcode version: 8.2.1
>> WebDriverAgent version: 1.0.41
>> xctest-client.js:170:14 [master] pid:22732 2017-02-28 10:41:49.009 xcodebuild[23231:309181]  IDETestOperationsObserverDebug: Writing diagnostic log for test session to:

第二台设备
>> macaca-ios.js:153:12 [master] pid:21863 Trying to start wda server...
>> xctest-client start with port: 8910
>> xctest-client.js:234:14 [master] pid:21863 xcode version: 8.2.1
>> WebDriverAgent version: 1.0.41
>> xctest-client.js:170:14 [master] pid:21863 2017-02-28 10:11:01.207 xcodebuild[21895:291402]  IDETestOperationsObserverDebug: Writing diagnostic log for test session to:


报告

报告加上了截屏,上图

点击 ScreenShot 跳转到截图页面

github 项目

项目地址具见 github,下载即可用
https://github.com/baozhida/macaca-multi-iosdriver

下载项目,打开两个终端,分别在项目的目录下执行,请根据自己的实际情况修改 app 名称 udid 等等信息

macaca server --verbose -p 3456

macaca server --verbose -p 3457

java 代码

栗子是基于 wd.java 编写的测试用例,testng 控制设备和端口号对应关系,并发执行,详细的见代码吧,欢迎试用

java 初始化代码, porps.put("proxyPort", Integer.parseInt(proxyport)); 这个端口是 testng 参数传入的,

public MacacaClient initDriver() throws Exception {
        initcount = initcount +1;
        System.out.println("-----设备"+udid+"---第"+initcount+"次初始化-------------");
        String platform = "IOS";

        JSONObject porps = new JSONObject();
        porps.put("platformName", platform);
        porps.put("app", "./app/xxx.app");
        //0: 启动并安装 app。1 (默认): 卸载并重装 app。 2: 仅重装 app。3: 在测试结束后保持 app 状态。
        porps.put("reuse", 3);
        porps.put("udid", udid);
        porps.put("proxyPort", Integer.parseInt(proxyport));
        JSONObject desiredCapabilities = new JSONObject();
        desiredCapabilities.put("desiredCapabilities", porps);
        desiredCapabilities.put("host", "127.0.0.1");
        desiredCapabilities.put("port", Integer.parseInt(port)); 

        if(port.equals("3457")){
            driver.sleep(2000);
        }
        return driver.initDriver(desiredCapabilities); 
    }

testng 配置

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="IOS" parallel="tests" thread-count="2">
    <test name="IOSTest1">
        <parameter name="port" value="3456" />
        <parameter name="proxyport" value="8900" />
        <parameter name="udid" value="xxxxxxxxxxxxxxxxxxxxxxxx" />
        <classes>
            <class name="testngcase.ios.IOSAppTest" />
        </classes>
    </test>

    <test name="IOSTest2">
            <parameter name="port" value="3457" />
            <parameter name="proxyport" value="8910" />
            <parameter name="udid" value="xxxxxxxxxxxxxxxxxxxxxx" />
        <classes>
            <class name="testngcase.ios.IOSAppTest" />
        </classes>
    </test>
</suite>


↙↙↙阅读原文可查看相关链接,并与作者交流