iOS 测试 iOS 远程真机实现讨论帖!!

yxys01 · 发布于 2017年08月11日 · 最后由 weamylady 回复于 2017年09月21日 · 2438 次阅读
本帖已被设为精华帖!

如题,最近公司看见MTC实现的远程真机,需要我去攻坚,但是由于技术储备以及对测试的不了解,没能攻克,希望在这里和大家一起讨论,一起解决这个问题。。。好东西一起分享嘛~~~
嘛,我先来说下我的大概思路吧:

页面显示

先前不是有ios-minicap可以通过不断的自动截图来显示iOS页面的实时显示嘛,基于这个框架可以实现页面的回显。具体安装步骤可以看一下我在CSDN里面写的ios-minicap安装使用指南

真机连接

连接协议主要是用的usbmuxd Proxy,这个主要还是通过libimobiledevice协议库来实现安装啊截图啊日志啊什么的

然后是Facebook提供的绝大多数都在使用的WebdriverAgent,可以直接用WebSocket通讯发送命令(ps:我的WDA特别傲娇各种找我麻烦,特别爱报operation never finished bootstrapping的错,https://testerhome.com/topics/9666,这里特别讲了一下我遇到的两个大麻烦)

操纵实现

有两个方案
一、是@codeskyblue 大神写的wdaproxy,看了下好像是用go语言写的,哇,萌新瑟瑟发抖ing

大概是这样的:

 tap: function(x, y) {
          var self = this;
          return $.ajax({
            url: "/session/" + self.sessionId + "/wda/tap/0",
            method: "POST",
            data: JSON.stringify({
              x: x,
              y: y
            }),
          }).then(function(ret) {
            if (ret.status !== 0) {
              console.log(ret.value);
            } else {
              return "Success";
            }
          })
        },

initScreenSize: function() {
          $.\
          ({
              url: "/status",
            })
            .then(function(ret) {
              this.sessionId = ret.sessionId;
              return $.ajax({
                url: "/session/" + ret.sessionId + "/window/size",
              })
            }.bind(this))
            .then(function(ret) {
              this.display.width = ret.value.width;
              this.display.height = ret.value.height;
            }.bind(this))
        },

这个其实是@weamylady 给我说的,so,有什么其他的想法也来讨论一下吧。

二、百度MTC项光特大佬提的,用iOS的私有API XCEventGenerator来实现不同类型的屏幕触控事件

关于这个要多谢@zhangzhao_lenovo 大神提供了两个地址:
swift:
https://github.com/zalando/SwiftMonkey/blob/master/SwiftMonkey/MonkeyXCTestPrivate.swift

oc的wda:
https://github.com/facebook/WebDriverAgent/blob/master/PrivateHeaders/XCTest/XCEventGenerator.h

或者通过iOS-Runtime-Headers来获取iOS的私有API

还有个说法是:
通过iproxy工具把接口映射到宿主机
宿主机通过curl命令的方式实现对设备的控制

希望这篇文章对大家实现iOS远程真机有帮助,也希望得到其他大神朋友们的帮助,跪谢!
同时也很感谢TesterHome这个平台,让我学习了很多有用的东西,希望TesterHome越做越好!

照例,在最后@几个大神防止帖子沉下去。。。。

@seveniruby @xdf @junhe (最近看着几位大神的文章比较多~~~~)

2017-8-14

上周我开了这个讨论话题,多谢@seveniruby思寒的加精让我觉得这个话题还是有实现的必要性的~
现在我讲一下我现在觉得可行性较高的一套实现思路,希望社区里面大神们也帮我参考参考,也希望能帮助更多人得到iOS远程真机实现的思路。

思路

首先,通过ios-minicap,我们可以获取一个Web端的页面,这个页面通过不断的对真机进行截图实现实时显示真机页面的功能;

然后,我们可以通过js对获取到的Web页面进行事件控制(包括鼠标的拖拽,点击,长按等);

其次,我们可以使用WDA作为PC端与真机进行连接的工具,调用苹果的私有API XCEventGenerator来实现PC端对真机的触控事件;

再其次,通过js的事件控制来调用WDA,实现Web端对PC端的操纵,最后达到Web端控制真机的触控;

最后,通过ios-minicap再实时回显真机上被WDA触控导致的操作,完成iOS远程真机的实现。

难点:

1.如何调用苹果的私有API XCEventGenerator来实现PC端对真机的触控事件

2.如何通过js实现鼠标的拖拽,点击,长按等事件,达到调用WDA的目的

2017-10-16

时隔两个月,现在基本有了iOS远程真机的解决方案——iOS-remote,感谢weamylady2的分享,安装使用详情可见https://testerhome.com/topics/10466

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
共收到 34 条回复
1134

我只是打酱油的,要搞这个还得恶补JS😖

25f875
yxys01 · #2 · 2017年08月11日 作者
1134weamylady 回复

大佬请不要这么说~~~~

6853

我也只是随便写写

110

给个思路,xcode9 出来之后,可以远程 debug,是不是能借助这条通道?

104 seveniruby 将本帖设为了精华贴 08月13日 15:08
5462

说一个不太沾边的想法,假如有一种硬件"屏幕”,替换掉现有手机的屏幕,这个新“屏幕”可以把视频信息转换到web上并模拟触控,那就可以实现所有类型手机的远程控制了,不过实现这个需要拆解手机,可能比较麻烦,估计目前市面上也没有这种东西。

25f875
yxys01 · #7 · 2017年08月14日 作者
5462blueshark 回复

这个如果能做到,屏幕本身就是信息处理中心了,估计那个时候手机就只有个屏幕了吧,也就更薄了,不过对我们还是有点远~~现在我们还是讨论通过软件方面来实现远程控制吧

9260

很赞哟

25f875
yxys01 · #9 · 2017年08月15日 作者

一起讨论实现嘛~

69ae3c

问楼主个问题 就是 ios-minicap 的截图速度跟facebook的WDA里面的截图速度比怎么样@yxys01

25f875
yxys01 · #11 · 2017年08月15日 作者
69ae3cpliue 回复

前者快得多耶~

69ae3c

@yxys01 我看了下 ios-minicap源码都是处理图片的 具体的截取动作是不是在cmake做的还是其他原理呀

25f875
yxys01 · #13 · 2017年08月15日 作者
69ae3cpliue 回复

这个我也在研究~但是还没找到是怎么实现截取的~~~你如果找到了我们可以一起分享嘛

69ae3c

我现在有两套方案都是跟这个有关 一个是在执行自动化的时候 去实时获取页面截图 因为调用IOS原生的ReplayKit没有提供接口 所以就把图片合成视频 第二个就是我做的一个实时操控iphone的也需要获取图片 都是使用的wda的screenshot 差不多100-200ms一张

Ba19ad

萌新提供个思路,不知道是否正确。iosApp端作为服务器接收iosminicap的点击请求,调用私有api

1902

1.如何调用苹果的私有API XCEventGenerator来实现PC端对真机的触控事件

楼上说的思路应该是正确的,这个应该通过app来实现,类似stf services

17楼 已删除
69ae3c

@lancelot_mn 可以参考下facebook的webdriveragent和阿里的XCTestWD

19楼 已删除
20楼 已删除
25f875
yxys01 · #21 · 2017年08月21日 作者

能给个联系方式私聊下吗?qq微信皆可。。。

22楼 已删除
Ba19ad

楼主是在将ios_minicap弄到atx里?

2d4b73

MTC的远程真机,是我们家技术支持的,在真机页面的右下角可以看到,由苏州跬步支持。有疑问,可以直接私聊完😇

6853

你要的打包命令

go generate ./web
go build -tags vfs
4944

怎么没在你们平台上看到iOS的真机远程呢

2d4b73
4944wangbin039 回复

网站:http://www.bugzero.cn/index,你打开这个网站试试

6853

做的还不错,不过没有苹果手机呀,Android也没有远程终端

2d4b73
6853codeskyblue 回复

iOS正在沟通更好的方案,Android是有的哟~

5462

你们这界面做的真不错,方便透露下做成这样花了多少时间和人力吗?

2d4b73
5462blueshark 回复

布局方面是后来改的,css部分花了1天。从0开始估计一个月

1134

看了百度的远程真机方案,感觉还是ios-minicap回显+wda远程操控做起来比较简单,这个月想要把这个搞出来,大家一起讨论下咯

1134

给位大佬好,我这边已经用ios-minicap+Jfinal+Tomacat把屏幕回显做出来了,屏幕监听事件借用了wdaproxy项目中的js。
今天在调tap事件,遇到一个大问题卡住了:
1,先启动WebDriverAgent,再启动ios-minicap,那么在WDA的进程会多出一条日志,然后卡死了。感觉是iOS-minicap也在某个地方调用了WDA,后续的tap操作就没办法执行。
2,如果在ios-minicap启动之后,再启动WDA,那么在向ios-minicap发起socket获取截图,WDA同样会出现一样的日志,然后卡死。

WDA日志如下:

99-6-88-54:WebDriverAgent waterhuang$ xcodebuild -project WebDriverAgent.xcodeproj -scheme WebDriverAgentRunner -destination 'id=bb7787b7ba9d57bb6f9c84273d22fe3204d1e547' test
2017-09-14 16:44:46.386 xcodebuild[20603:567818]  IDETestOperationsObserverDebug: Writing diagnostic log for test session to:
/Users/waterhuang/Library/Developer/Xcode/DerivedData/WebDriverAgent-dikkwtrisltbeobjmfvpthwwekvs/Logs/Test/86F41E4A-F9BF-4585-B2A9-C25DF7D17CCC/Session-WebDriverAgentRunner-2017-09-14_164446-6Y1V40.log
2017-09-14 16:44:46.387 xcodebuild[20603:567817] [MT] IDETestOperationsObserverDebug: (727C4322-FEB3-4E83-8C45-35F618841E8D) Beginning test session WebDriverAgentRunner-727C4322-FEB3-4E83-8C45-35F618841E8D at 2017-09-14 16:44:46.387 with Xcode 8E3004b on target <DVTiOSDevice: 0x7fe2fcfdb1c0> {
        deviceSerialNumber:         C8QP5BQHG5MP
        identifier:                 bb7787b7ba9d57bb6f9c84273d22fe3204d1e547
        deviceClass:                iPhone
        deviceName:                 iPhone
        deviceIdentifier:           bb7787b7ba9d57bb6f9c84273d22fe3204d1e547
        productVersion:             10.3.3
        buildVersion:               14G60
        deviceSoftwareVersion:      10.3.3 (14G60)
        deviceArchitecture:         arm64
        deviceTotalCapacity:        12241596416
        deviceAvailableCapacity:    8145756160
        deviceIsTransient:          NO
        ignored:                    NO
        deviceIsBusy:               NO
        deviceIsActivated:          YES
        deviceActivationState:      Activated
        isPasscodeLocked:           NO
        deviceType:                 <DVTDeviceType:0x7fe2fcca88c0 Xcode.DeviceType.iPhone>
        supportedDeviceFamilies:    (
    1
)
        applications:              (null)
        provisioningProfiles:      (null)
        activityProgress:          -2
        activityTitle:             
        hasInternalSupport:        NO
        isSupportedOS:             YES
        developerDiskMountError:   (null)
(null)
    bootArgs:                  <unavailable>
        } (10.3.3 (14G60))
=== BUILD TARGET WebDriverAgentLib OF PROJECT WebDriverAgent WITH CONFIGURATION Debug ===

Check dependencies

=== BUILD TARGET WebDriverAgentRunner OF PROJECT WebDriverAgent WITH CONFIGURATION Debug ===

Check dependencies

MDMCreateDeltaDirectory:1920 calling MDMDirectoryDiff with:
state->old_bundle: /var/folders/lq/q_5j5j1d2d5_v7w4bxmhgv5r0000gn/C/com.apple.DeveloperTools/All/Xcode/EmbeddedAppDeltas/33d6e04dc03b69e6e6e6fd8dea37958a/bb7787b7ba9d57bb6f9c84273d22fe3204d1e547/WebDriverAgentRunner-Runner.app
state->new_bundle: /Users/waterhuang/Library/Developer/Xcode/DerivedData/WebDriverAgent-dikkwtrisltbeobjmfvpthwwekvs/Build/Products/Debug-iphoneos/WebDriverAgentRunner-Runner.app
state->dst_bundle: /var/folders/lq/q_5j5j1d2d5_v7w4bxmhgv5r0000gn/C/com.apple.DeveloperTools/All/Xcode/EmbeddedAppDeltas/WebDriverAgentRunner-Runner.app.NXYEQh/WebDriverAgentRunner-Runner.app_sparse.ipa/Payload//WebDriverAgentRunner-Runner.app, binaryDiff flag: FALSE
    dst_ipa: /var/folders/lq/q_5j5j1d2d5_v7w4bxmhgv5r0000gn/C/com.apple.DeveloperTools/All/Xcode/EmbeddedAppDeltas/WebDriverAgentRunner-Runner.app.NXYEQh/WebDriverAgentRunner-Runner.app_sparse.ipa
MDMDirectoryDiff_block_invoke:1473 calling writeDictToFile with: /var/folders/lq/q_5j5j1d2d5_v7w4bxmhgv5r0000gn/C/com.apple.DeveloperTools/All/Xcode/EmbeddedAppDeltas/WebDriverAgentRunner-Runner.app.NXYEQh/WebDriverAgentRunner-Runner.app_sparse.ipa/ManifestCache.plist
writeDictToFile:1278 ==== Successfully wrote Manifest cache to /var/folders/lq/q_5j5j1d2d5_v7w4bxmhgv5r0000gn/C/com.apple.DeveloperTools/All/Xcode/EmbeddedAppDeltas/WebDriverAgentRunner-Runner.app.NXYEQh/WebDriverAgentRunner-Runner.app_sparse.ipa/ManifestCache.plist
2017-09-14 16:45:13.717753+0800 XCTRunner[2688:701460] Running tests...
2017-09-14 16:45:14.727374+0800 XCTRunner[2688:701460] Continuing to run tests in the background with task ID 1
Test Suite 'All tests' started at 2017-09-14 16:45:14.890
Test Suite 'WebDriverAgentRunner.xctest' started at 2017-09-14 16:45:14.894
Test Suite 'UITestingUITests' started at 2017-09-14 16:45:14.895
Test Case '-[UITestingUITests testRunner]' started.
    t =     0.00s     Start Test at 2017-09-14 16:45:14.899
    t =     0.01s     Set Up
2017-09-14 16:45:14.936272+0800 XCTRunner[2688:701560] [User Defaults] Failed to write value for key AutomationDisableFauxCollectionCells in CFPrefsPlistSource<0x1701056a0> (Domain: com.apple.Accessibility, User: kCFPreferencesCurrentUser, ByHost: No, Container: (null)): setting preferences outside an application's container requires user-preference-write or file-write-data sandbox access, switching to read-only
2017-09-14 16:45:15.031058+0800 XCTRunner[2688:701460] Built at Sep 14 2017 09:19:49
2017-09-14 16:45:15.224069+0800 XCTRunner[2688:701460] ServerURLHere->http://99.6.91.22:8100<-ServerURLHere
    t =     3.20s     Find the Application "local.pid.53" 0x1740b6c20
    t =     3.20s         Snapshot accessibility hierarchy for local.pid.53
    t =     3.46s     Find the Application "local.pid.53" 0x1740b6c20
    t =     3.46s         Use cached accessibility hierarchy for local.pid.53
    t =     3.46s     Use cached accessibility hierarchy for local.pid.53
    t =     3.49s     Find the Application "local.pid.53" 0x1740b6c20
    t =     3.50s         Snapshot accessibility hierarchy for local.pid.53
    t =     3.64s     Find the Application "local.pid.53" 0x1740b6c20
    t =     3.64s         Use cached accessibility hierarchy for local.pid.53
2017-09-14 16:45:25.314 xcodebuild[20603:567915]  IDETestOperationsObserverDebug: Writing diagnostic log for test session to:
/Users/waterhuang/Library/Developer/Xcode/DerivedData/WebDriverAgent-dikkwtrisltbeobjmfvpthwwekvs/Logs/Test/86F41E4A-F9BF-4585-B2A9-C25DF7D17CCC/Session-WebDriverAgentRunner-2017-09-14_164525-Nq4VNG.log
2017-09-14 16:45:25.315 xcodebuild[20603:567817] [MT] IDETestOperationsObserverDebug: (5246C677-3941-41EA-98A8-853990396271) Beginning test session WebDriverAgentRunner-5246C677-3941-41EA-98A8-853990396271 at 2017-09-14 16:45:25.314 with Xcode 8E3004b on target <DVTiOSDevice: 0x7fe2fcfdb1c0> {
        deviceSerialNumber:         C8QP5BQHG5MP
        identifier:                 bb7787b7ba9d57bb6f9c84273d22fe3204d1e547
        deviceClass:                iPhone
        deviceName:                 iPhone
        deviceIdentifier:           bb7787b7ba9d57bb6f9c84273d22fe3204d1e547
        productVersion:             10.3.3
        buildVersion:               14G60
        deviceSoftwareVersion:      (null)
        deviceArchitecture:         arm64
        deviceTotalCapacity:        12241596416
        deviceAvailableCapacity:    8145756160
        deviceIsTransient:          NO
        ignored:                    YES
        deviceIsBusy:               NO
        deviceIsActivated:          NO
        deviceActivationState:      Activated
        isPasscodeLocked:           NO
        deviceType:                 <DVTDeviceType:0x7fe2fcca88c0 Xcode.DeviceType.iPhone>
        supportedDeviceFamilies:    (null)
        applications:              (null)
        provisioningProfiles:      (null)
        activityProgress:          -2
        activityTitle:             
        hasInternalSupport:        NO
        isSupportedOS:             NO
        developerDiskMountError:   (null)
(null)
    bootArgs:                  <unavailable>
        } ((null))


6853
1134weamylady 回复

给你说下顺序,启动minicap 然后启动socket获取图像,然后启动wda

1134
6853codeskyblue 回复

多谢,这个顺序是可以。有没有解决的方法?这个顺序启动的话,还是挺慢的。

1134

@yxys01 有空加我微信聊聊吧,xiaotao4495,目前已经把Demo写出来了,但还是存在很多的问题,尤其是运行的顺序这个有待优化。

13419
1134weamylady 回复

https://github.com/openstf/ios-minicap/issues/14

This is because the active USB configuration changes. Normally, it's "PTP + Apple Mobile Device". When minicap (or QuickTime) runs, it changes to "PTP + Apple Mobile Device + Valeria". This causes a reconnection. When minicap ends, the configuration changes back, again triggering a brief disconnection. For that reason you must start minicap before anything else and keep it running the whole time.

1134
13419kai0519 回复

minicap要这个机制就没办法了,目前我已经把顺序启动写好了,就是时间有点长,刷新网页之后需要20秒钟才能用起来。

1134

https://github.com/weamylady2/iOS_remote

Demo已上传,欢迎大家指点意见。

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册