Appium appium 怎么同时在不同手机上执行相同用例 (过兼容性)

willie · 2016年10月25日 · 最后由 小小的蜗牛 回复于 2020年02月09日 · 3680 次阅读

1、使用 usb 连接的 adb,python 写的脚本。
2、单个手机的执行都没问题,现在想连接多个手机同时执行测试。
3、问题点在于 adb 方式能读取到多个设备但每次执行时候即使手动新开 appium 服务,还是会执行同一个服务的 id。先开的 server 被新的 server 踢掉
自己想到的方法是使用无线连接 adb,分别指定端口。但具体还是实现不了。
求大神分享下,具体怎么开启多个 appium 服务和连接多设备。

部分实现写在 #3,请忽略写的线程,通过后面的运行发现这段线程无效
问题解决了一部分,谢谢 #16 的朋友。desi_capab 里面增加了 udid 字段就可以了
2 个手机可以在 2 个服务中启动被测应用了。

引发了新的问题,2 个手机只是启动了应用但用例并未执行。
而且不是并行的,是一个手机执行了启动完成后另一个手机开始执行启动(单个手机时候是可以执行用例的)
这部分的并发请问用什么方式处理?还有为什么没有执行用例?

共收到 39 条回复 时间 点赞

启动脚本里面指定 udid 和端口

我这样做了,我做的循环获取 devices 和端口号自动增加。但是还是会第二个踢掉第一个。懂具体实现的说一下细节好么

threads=[]
def getConnDevice():
    devicesname=getDevices()
    desired_caps = {'platformName': 'Android', 'platformVersion': '6.0', 'appPackage': 'net.xxx.xxx', 'appActivity': '.MainActivity'}
    host=4719
    if len(devicesname)>1:
        devicesid=devicesname[0:]
        for i in devicesid:
            desired_caps['deviceName']=i
            host=host+1
            driver = webdriver.Remote('http://localhost:%d/wd/hub' %host, desired_caps)  
            t=threading.Thread(args=driver)
            threads.append(t.start())
            continue
        threads.append(t.join())       

之前的思路大概就是这样。getdevices()获取所有 devices。写的比较糟。求一个清晰点的代码

4楼 已删除

没有清晰的代码,只有思路。
1.appium 在启动的时候,需要绑定端口号。这个端口号和 desired_caps 里面的端口是一致的。可以才用命令行启动的方式:
"C:\Program Files (x86)\Appium\node.exe" "C:\Program Files (x86)\Appium\node_modules\appium\lib\server\main.js" --no-reset --address 127.0.0.1 --port 4723 --bootstrap-port 4824 --platform-name Android --platform-version 23 --automation-name Appium --device-name "f0decf5c" --log-no-color --session-override --log "C:\Users\admin\Desktop\1\t.log"
2.在设置 desired_caps 时,不是每台设备的 platformVersion 都是 6.0,区别设置

willie #12 · 2016年10月25日 Author

#5 @terry_tan谢谢回复。
appium 那边我现在是手动起多个服务,端口号我都改的和程序一样,2 个设备我就起 2 个端口号 +1。例如一个服务是--port 4723 ;一个是--port 4724 这样。
另:--bootstrap-port 4824 这个必须要写么?我写和不写运行起来没差别。
2、platformVersion 这个我到没特别注意,一个的时候不是 6.0 的这样写没什么问题。

简单来说:

  1. 几个手机对应几个 appium 服务;
  2. appium 服务的端口要和手机 driver 端口一致
  3. 手机的 directed_caps 要单独配置,这个不同的手机配置不一样
willie #14 · 2016年10月25日 Author

之前有看到 appium 服务器形式解决,我也不知道是怎么实现,我现在是电脑上装一个 appium,多个手机是就多起几次 appium 修改端口这样。目前我上面写的缺点就是 usb 只支持一个 adb 连接。怎么改成无线连接。支持多个 adb。

#8 楼 @Last_One_Standing 没玩过无线,一直都是 USB 连接。

willie #15 · 2016年10月25日 Author

#9 楼 @terry_tan 你使用 usb 连接多个设备时候可以同时跑么?

启动 appium 的命令是:appium -p 4723 -bp 4724 -u xxxx
有几个设备就启动几个 appium,启动的时候端口号是作为参数传递的,也就是你自动生成的端口。
driver 初始化的时候需要端口号,就是那个 4723,而 cap 需要设备 id
这样你代码和 appium 的端口就确定了,appium 和设备的端口也确定了,运行起来多少个设备都不会影响的

willie #12 · 2016年10月25日 Author

#11 楼 @sailen

如图,设置和运行后,2 个不同的 session-id 执行到下面都变成同一个设备了。这是为什么

#12 楼 @Last_One_Standing driver 初始化时有设置端口吗?cap 有设置 udid 吗?
如果都设置好了不应该 啊

willie #19 · 2016年10月25日 Author

#13 楼 @sailen 你看看我 3 楼的代码, devices 是循环获取的,你说的驱动初始化设置端口是什么?adb 端口么?

程序里打出来的应该是对的。但结果就是不知道为什么运行成上面 12 楼那截图那样了。只能跑一个手机

willie #20 · 2016年10月25日 Author


刚才查看了一下 adb forward 上面的结果可能与这个有关系,
只有一个设备的。且使用了 3 个不同的端口

desired_caps 用 udid 指定具体设备的唯一识别号(adb device 看到的设备名称),不要用 deviceName 。

willie #17 · 2016年10月26日 Author

#16 楼 @chenhengjie123
{"udid":"69T7N15C22001823","appActivity":".MainActivity","appPackage":"net.xxx.xxxx","platformVersion":"6.0","platformName":"Android"}}

info: Client User-Agent string: Python-urllib/3.5
info: [debug] Got configuration error, not starting session
info: [debug] Cleaning up appium session
info: [debug] Error: The following desired capabilities are required, but were not provided: deviceName

使用 udid 代替 devicename 直接报错了。

willie #18 · 2016年10月26日 Author

后面我没替换,保留 devicename 然后增加了 udid 字段就可以 2 个手机可以分别跑了,但不是同步跑的,用例也没执行,只是 2 个手机都启动了被测应用。谢谢#16 楼 @chenhengjie123 给的启发。

想要的功能实现了吗?

#19 楼 @1045235634 只实现了多设备启动应用但是没有运行测试用例。

你不会代码里都是 static 对象吧

willie #22 · 2016年10月26日 Author

#21 楼 @dongdong 说的具体点好么 。我 python 是自学的语法不太清楚。我是在一个类里使用一个 driver 获取 2 个设备的 desired_caps。想用 threading 实现,结果不行。

#22 楼 @Last_One_Standing 啊 我不懂大 python 啊...我的意思就是你的变量有没有作用域的问题

#3 楼 @Last_One_Standing

driver = webdriver.Remote('http://localhost:%d/wd/hub' %host, desired_caps)

改为

driver = webdriver.Remote('http://localhost:%d/wd/hub' %host, desired_caps.copy())

因为 dict 是引用,单从代码使用上看出有这么个问题,修改后再试试,最好把主要的代码实现逻辑贴一下,不然很难看出问题。。。(有关自己业务的可以隐掉)

#3 楼 @Last_One_Standing

t=threading.Thread(args=driver)
threads.append(t.start())

这线程写的不对吧,建议你自己先学习一下线程的基础知识,threading 的基本用法,这应该是 case 没有执行的原因

willie #26 · 2016年10月27日 Author

#25 楼 @zhycbd 我也怀疑是线程没写好,控制台可以显示开启了 2 个线程,但没实际用途。。我的想法是 driver 获取到一个手机的信息后开启一个线程,循环获取第二个设备信息后在开启一个线程,由于都是由 driver 当容器,这点是不是不可以?我看网上说的一般都是在方法外面使用线程。感觉不会套用。我在看看相关资料。

你的多线程有问题,要用到线程池,你只是起了多个 driver,但是执行的时候没有调用。有空研究下生产者,消费者模式。(比方你请多个人给你买了许多苹果,但是吃的时候就你一个人。)

willie #31 · 2016年10月27日 Author

#27 楼 @snake 谢谢回复,的确是后面没有调用 driver。多线程的确有点搞晕我了。

设置好 bootstarp 端口和 Server 的端口就好了吧,如果要同时启动多个,这个肯定要设置的。
appium -p 4723 -bp 4724 -u xxxx -p 和-bp 后面的端口都要修改。然后就是写多线程,让它同时跑就行。

我用这个在 mac 终端是可以的但是 java String[] cmds = {"/bin/sh","-c","/Applications/Appium.app/Contents/Resources/node_modules/.bin/appium appium -a 127.0.0.1 -p 4723"};
process = Runtime.getRuntime().exec(cads);
就无法正常启动

willie #34 · 2016年11月03日 Author

#29 楼 @cloudwind 可以启动多个,但是没有执行用例,就是多线程不会写。你们是怎么写的线程呢。

willie #32 · 2016年11月03日 Author

#30 楼 @sunyy java 写的么?你上面那句话里面 exec 里面要执行的是 cmds?你写的是 cads 呢

不好意思回帖的时候 copy 错了

楼主的问题解决了吗?我现在跟你当时的情况一样,也是从头开始学习,现在想在不同的 手机上执行用例,但是还没找到方法 。

多设备应用是同时启动了,但是运行 case 时,就是一个先运行,等运行完毕后,另一个才会再运行,各位有解决这个的吗??是我的多线程写的有问题吗??

python 的多线程不是真正意义上的多线程,由于 GIL 的存在,每一个时间点只会有一个线程在运行

楼主的问题是,无论启动几个 appium 服务,比如启动了,3333,3334,3335,但是每次以循环结束的最终端口:3335 去连接的,所以只会在一台设备执行测试。现在也遇到了这个问题,我觉得可以考虑一下,使用线程局部变量去试一试)本人没试过,只会有一些思路)

请问,多线程同时执行用例的解决了没

willie 回复

麻烦问下这个问题解决了吗?我也遇到这个问题了

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