简介

前面课程只是启动了单个appium服务,只能控制单台设备。如果需要针对多台设备测试那么该如何处理?而且发现群里的小伙伴们也在时不时地在讨论这个问题,想知道怎么实现的,于是宏哥就决定写一片这样的文章来给小伙伴们,答答疑,解解惑。希望对各位小伙伴或者童鞋们有所帮助,可以是你们豁然开朗。

启动多个appium服务

首先看下面两个启动appium服务案例。

启动appium服务1

启动appium 服务2

上面案例我们启动了2个不同的appium服务器,他们通过不同的端口来区分不同的服务;如同百米赛跑要给不同的运动员安排不同的赛道,每个运动员也只能在自己指定的赛道进行比赛。

1.启动appium服务,可以用命令行模式

比如

第一个appium服务,可以指定一个端口 -p 4723,然后指定一个设备名称 -u 【AVD模拟器】,也就是-U参数(adb devices可以查看),-bp是指定bootstrap-port

(多个appium启动链接多个android设备时需要设置不同的 bootstrap-port )

appium -a 127.0.0.1 -p 4723 -bp 4726 -U ML5RRPCUWO

第二个appium 服务指定设备名称【夜神模拟器】

appium -a 127.0.0.1 -p 4724 -bp 4725 -U 127.0.0.1:62001

Appium常用参数

参数

默认值

含义

-U, --udid

null

连接物理设备的唯一设备标识符

-a, --address

0.0.0.0

监听的 ip 地址

-p, --port

4723

监听的端口

-bp, --bootstrap-port

4724

连接Android设备的端口号(Android-only)

-g, --log

null

将日志输出到指定文件

--no-reset

false

session 之间不重置应用状态

--session-override

false

允许 session 被覆盖 (冲突的话)

--app-activity

null

打开Android应用时,启动的 Activity(Android-only) 的名字

--app

null

本地绝对路径_或_远程 http URL 所指向的一个安装包

更多参数请输入命令: appium -h

Appium安卓手机每次运行时都要安装 Unlock、Setting解决方案

首先通过如下命令找到appium的安装路径

where appium

1.打开 C:\Users\Shuqing\AppData\Roaming\npm\node_modules\appium\node_modules\appium-android-driver\lib 中的android-helpers.js

#注释475行如下代码

//await helpers.pushSettingsApp(adb);

#注释486行如下代码

//await helpers.pushUnlock(adb);

2.打开C:\Users\Shuqing\AppData\Roaming\npm\node_modules\appium\node_modules\appium-android-driver\build\lib中的android-helpers.js

#注释1128行下面这行代码

//return _regeneratorRuntime.awrap(helpers.pushSettingsApp(adb));

#修改为如下:

$.abrupt('return', defaultIME);

#注释1163行下面这行代码

//return _regeneratorRuntime.awrap(helpers.pushUnlock(adb));

#修改如下:

$.abrupt('return', defaultIME);

修改完成后重启Appium服务即可,如果新设备没有这个两个守护App可以手动安装这两个App到设备。

Appium Setting路径 :

{appium安装路径}\node_modules\_io.appium.settings@@io.appium.settings\app\build\outputs\apk\settings_apk-debug.apk

eg:

C:\Users\Shuqing\AppData\Roaming\npm\node_modules\appium\node_modules\_io.appium.settings@@io.appium.settings\app\build\outputs\apk\settings_apk-debug.apk

Unlock app路径:

appium安装路径\node_modules\_appium-unlock@@appium-unlock\bin \unlock_apk-debug.apk

eg:

C:\Users\Shuqing\AppData\Roaming\npm\node_modules\appium\node_modules\_io.appium.settings@@io.appium.settings\app\build\outputs\apk\unlock_apk-debug.apk

多设备启动

前面我们已经启动了多个appium服务,那么接下来我们可以基于这些服务来启动不同的设备。

测试场景

连接以下2台设备,然后分别启动考研帮App

设备1:127.0.0.1:62001(夜神模拟器)

设备2:emulator-5554(AVD模拟器)

代码实现

desired_caps.yaml

 platformName: Android
 platformVersion:
 deviceName:
 app: C:\Users\DELL\Downloads\kaoyanbang.apk
 appPackage: com.tal.kaoyan
 appActivity: com.tal.kaoyan.ui.activity.SplashActivity
 noReset: False
 unicodeKeyboard: True
 resetKeyboard: True
 ip: 127.0.0.1

multi_device.py

 # coding=utf-
 # .先设置编码,utf-8可支持中英文,如上,一般放在第一行

 # .注释:包括记录创建时间,创建人,项目名称。
 '''
 Created on --
 @author: 北京-宏哥   QQ交流群:
 Project:学习和使用appium自动化测试-并发测试
 '''
 # .导入模块
 from appium import webdriver

 import yaml

 from time import ctime

 with open('desired_caps.yaml', 'r')as file:
     data = yaml.load(file)

 devices_list = ['127.0.0.1:62001', 'emulator-5554']

 def appium_desire(udid, port):
     desired_caps = {}

     desired_caps['platformName'] = data['platformName']

     desired_caps['platformVersion'] = data['platformVersion']

     desired_caps['deviceName'] = data['deviceName']

     desired_caps['udid'] = udid

     desired_caps['app'] = data['app']

     desired_caps['appPackage'] = data['appPackage']

     desired_caps['appActivity'] = data['appActivity']

     desired_caps['noReset'] = data['noReset']

     print('appium port: %s start run %s at %s' % (port, udid, ctime()))

     driver = webdriver.Remote('http://' + str(data['ip']) + ':' + str(port) + '/wd/hub', desired_caps)

     return driver

 if __name__ == '__main__':
     appium_desire(devices_list[], )

     appium_desire(devices_list[], )

代码运行结果

设备运行结果

夜神模拟器

AVD模拟器

多进程并发启动设备

上面的案例设备启动并不是并发进行的,而是先后执行。那个设备在前边就先执行那个,那么如何实现2台设备同时启动,并启动App呢?

测试场景

同时启动2台设备:'emulator-5554'和'127.0.0.1:62001'并打开考研帮app

实现思路

可以使用Python多线程或者多进程实现。这里我们推荐使用多进程( multiprocessing) 原因如下:

  • 多进程中,同一个变量,各自有一份拷贝存在于每个进程中,互不影响。
  • 而多线程中,所有变量都由所有线程共享,所以,任何一个变量都可以被任何一个线程修改,因此,线程之间共享数据最大的危险在于多个线程同时改一个变量,容易把内容给改乱了。

有兴趣的小伙伴或者童鞋们可以看一下以下的知识点:

  • 线程与进程
  • Python多进程
  • python多线程

代码实现

multi_devices_sync.py

 # coding=utf-
 # .先设置编码,utf-8可支持中英文,如上,一般放在第一行

 # .注释:包括记录创建时间,创建人,项目名称。
 '''
 Created on --
 @author: 北京-宏哥   QQ交流群:
 Project:学习和使用appium自动化测试-并发测试
 '''
 # .导入模块
 from appium import webdriver

 import yaml

 from time import ctime

 import multiprocessing

 with open('desired_caps.yaml', 'r') as file:
     data = yaml.load(file)

 devices_list = ['127.0.0.1:62001', '127.0.0.1:62025']

 def appium_desired(udid, port):
     desired_caps = {}

     desired_caps['platformName'] = data['platformName']

     desired_caps['platformVersion'] = data['platformVersion']

     desired_caps['deviceName'] = data['deviceName']

     desired_caps['udid'] = udid

     desired_caps['app'] = data['app']

     desired_caps['appPackage'] = data['appPackage']

     desired_caps['appActivity'] = data['appActivity']

     desired_caps['noReset'] = data['noReset']

     print('appium port:%s start run %s at %s' % (port, udid, ctime()))

     driver = webdriver.Remote('http://' + str(data['ip']) + ':' + str(port) + '/wd/hub', desired_caps)

     driver.implicitly_wait()

     return driver

 # 构建desired进程租

 desired_process = []

 # 加载desied进程

 for i in range(len(devices_list)):
     port =  +  * i

     desired = multiprocessing.Process(target=appium_desired, args=(devices_list[i], port))

     desired_process.append(desired)

 if __name__ == '__main__':

     # 启动多设备执行测试

     for desired in desired_process:
         desired.start()

     for desired in desired_process:
         desired.join()

小结

Appium服务通过命令行appium启动报错 error: uncaughtException: Cannot find module 'internal/util/types'

  这个错误困扰了宏哥很久,不是找不到解决办法,而是宏哥在犹豫要不要试一下下边的所说的解决办法呢???因为前边的appium的环境都搭建好了,如果卸载了,安装了低版本的node,会不会引发一系列的其他环境不兼容的让人头疼的问题,等等的考虑吧!最后刚好碰到中秋节,时间充裕,宏哥痛定思痛的还是下定决心卸载试一下,毕竟活着就是不断地折腾的呗!最后宏哥试了一下是否可以安装一个高版本和低版本的node在一个系统中,你如果需要高版本的切换高版本的node,如果需要低版本的切换低版本的node,这样这个问题就会完美解决了,有兴趣的可以看一下宏哥的这篇文章:手把手告诉你如何安装多个版本的node(非常详细,非常实用)

解决方法:

是因为版本不匹配. 我装的appium版本是1.4.16,而node版本是v10.16.0,把node卸载了,装v6.9.4,完美解决~

node版本是v10.16.0

appium版本是1.4.16

v6.9.4下载: v6.9.4地址

您的肯定就是我进步的动力。如果你感觉还不错,就请鼓励一下吧!记得点波 推荐 哦!!!(点击右边的小球即可!(^__^) 嘻嘻……)

Appium+python自动化(三十六)- 士兵突击许三多 - 多个appium服务启动,多个设备启动,多进程并发启动设备-并发测试 - 上(超详解)的更多相关文章

  1. Appium+python自动化(二十七)-让你在手机找到溜冰一样的感觉666,溜得飞起来 - 低级滑动(超详解)

    简介 随着现在智能手机的普及和应用,小到五六岁或者更小的娃娃,老至七八十岁老头老太太都是智能手机的用户,基本上达到每个人都在用,每次在地铁或者公交上,就看看到这样的场面,手指不停地在手机屏幕上来来回回 ...

  2. Appium+python自动化(三十七)- 士兵突击许三多 - 多个appium服务启动,多个设备启动,多进程并发启动设备-并发测试 - 下(超详解)

    简介 接着上一篇继续看一下如何并发测试以及并发测试的过程中,可能遇到的问题,在这里宏哥把宏哥遇到的和小伙伴或者童鞋们,一起分享一下. Appium端口检测 问题思考 经过前面学习,我们已经能够使用py ...

  3. Appium+python自动化(十六)- ADB命令,知否知否,应是必知必会(超详解)

    简介 Android 调试桥(adb)是多种用途的工具,该工具可以帮助你你管理设备或模拟器 的状态. adb ( Android Debug Bridge)是一个通用命令行工具,其允许您与模拟器实例或 ...

  4. Appium+python自动化(十五)- Android 这些基础知识,你知多少???(超详解)

    简介 前边具体操作和实战已经讲解和分享了很多了,但是一些android的一些基础知识,你又知道多少了,你都掌握了吗?这篇就由宏哥给小伙伴们既是一个分享,又是对前边的一次总结.为什么要对这些做一个简单的 ...

  5. Appium+python自动化(十)- 元素定位秘籍助你打通任督二脉 - 上卷(超详解)

    简介 你有道灵光从天灵盖喷出来你知道吗,年纪轻轻就有一身横练的筋骨,简直百年一见的练武奇才啊,如果有一天让你打通任督二脉,那还不飞龙上天啊.正所谓我不入地狱谁入地狱,警恶惩奸维护世界和平这个任务就交个 ...

  6. 笨办法学Python(三十六)

    习题 36: 设计和调试 现在你已经学会了“if 语句”,我将给你一些使用“for 循环”和“while 循环”的规则,一面你日后碰到麻烦.我还会教你一些调试的小技巧,以便你能发现自己程序的问题.最后 ...

  7. Appium+python自动化(十二)- Android UIAutomator终极定位凶“胸”器(七)(超详解)

    简介 乍眼一看,小伙伴们觉得这部分其实在异性兄弟那里就做过介绍和分享了,其实不然,上次介绍和分享的大哥是uiautomatorviewer,是一款定位工具.今天介绍的是一个java库,提供执行自动化测 ...

  8. Appium+python自动化(十九)- 猴哥失散多年的混血弟弟还是妹妹- Monkey(猴子)参数(超详解)

    简介 前边几篇介绍了Monkey以及Monkey的事件,今天就给小伙伴们介绍和分享一下Monkey的参数. 首先我们看一下这幅图来大致了解一下: 1.Monkey 命令 基本参数介绍 -p <允 ...

  9. python第三十六课——2.迭代器对象

    满足前提: 1).必须是一个可迭代对象 2).可以被next()所作用的 举例: generator... 高效的检测一个对象是否是迭代器对象 需要使用collections模块中的Iterator类 ...

随机推荐

  1. 使用抽象工厂反射获取不到Dal层对象,未能加载文件或程序集......

    Put aside the fog and see the essence 解决问题之前,要明白问题为什么会出现 我相信能点开这篇帖子的人,都是具有探索精神的人,因为,只有心存疑问才会搜索 如果只想单 ...

  2. 【POJ - 3616】Milking Time(动态规划)

    Milking Time 直接翻译了 Descriptions 贝茜是一个勤劳的牛.事实上,她如此​​专注于最大化她的生产力,于是她决定安排下一个N(1≤N≤1,000,000)小时(方便地标记为0. ...

  3. exe、dos、bat等静默运行,后台运行,不弹窗的解决办法

    exe中 #pragma comment( linker, "/subsystem:windows /entry:mainCRTStartup" ) 1. WinExec(LPCS ...

  4. Python-PostgreSQL的使用

    一.安装PostgreSQL模块 yum install postgresql-devel pip3 install psycopg2 注意:安装时遇到./psycopg/psycopg.h:35:2 ...

  5. zabbix利用自带模板-监控mysql性能

    环境: zabbix3.4.4 mariadb 5.5.56 要求:  利用zabbix 自带的模板 监控mariadb 上的 并发连接数,慢查询数量,增删改查.请求流量带宽,mysql响应流量带宽等 ...

  6. json模块和pickle模块

    json模块和pickle模块 一.json模块 作用:用python写了一个程序,用java写了一门程序,这两个程序需要数据之间交流,就产生了一种多种语言通用的数据类型,json串. 序列化:把对象 ...

  7. JavaScript计算平方数的三种方法

    console.log(2*10**3) console.log(2*Math.pow(10,3)) console.log(2e3) console.log(2*1e3) console.log(2 ...

  8. Spring学习之旅(十)--MockMvc

    在之前的 Spring学习之旅(八)--SpringMVC请求参数 我们是通过在控制台输出来验证参数是否正确,但是这样做实在是太耗时间了,我们今天来学习下 MockMvc,它可以让我们不需要启动项目就 ...

  9. Elasticsearch核心技术(1)--- Docker容器中运行ES、Kibana、Cerebro

    Docker容器中运行ES,Kibana,Cerebro和Logstash安装与数据导入ES 想加强ES有关的知识,看了阮一鸣老师讲的<Elasticsearch核心技术与实战>收获很大, ...

  10. Java异常机制及异常处理建议

    1.Java异常机制 异常指不期而至的各种状况,如:文件找不到.网络连接失败.非法参数等.异常是一个事件,它发生在程序运行期间,干扰了正常的指令流程.Java通过API中Throwable类的众多子类 ...