前言

做android自动化的时候,启动一个appium服务,只能匹配一个手机去自动化执行。有时候想同一套代码,可以在不同的手机上执行,测下app在不同手机上兼容性。

这就需要启动多个appium服务了,并且android设备和appium要一一对应才行。

启动多个手机

1.这里以夜神模拟器和雷电模拟器为例,先启动这2个设备

2.adb devices查看设备名称,多个设备会显示多行数据

启动多个appium服务

1.启动appium服务,可以用命令行模式,在cmd里面启动,可以参考上一篇 appium命令行参数

比如第一个appium服务,可以指定一个端口4730,然后指定一个设备名称【雷电模拟器】,也就是-U参数(adb devices可以查看)

appium -a 127.0.0.1 -p 4730 -U emulator-5554 --no-reset

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

appium -a 127.0.0.1 -p 4740 -U 127.0.0.1:62001 --no-reset

yaml管理配置

1.运行不同手机时候,desired_caps的参数配置肯定也是需要多个的,如何高效的管理多个desired_caps配置呢?

这里我用yaml文件去管理,更方便查看

desired_caps = {
'platformName': 'Android', # 手机是Android还是ios
'deviceName': 'emulator-5554',
'platformVersion': '5.1.1', # android版本号
'noReset': True,
# apk包名 # aapt工具查看
'appPackage': 'com.taobao.taobao',
# apk的launcherActivity
'appActivity': 'com.taobao.tao.welcome.Welcome'
}

2.yaml文件配置如下:


- desc: 设备名称_雷电,appium启动服务端口号_4723
port: 4730
desired_caps:
platformName: Android
deviceName: emulator-5554
appPackage: com.taobao.taobao
noReset: !!bool True
udid: emulator-5554
appActivity: com.taobao.tao.welcome.Welcome - desc: 设备名称_夜神,appium启动服务端口号_4724
port: 4740
desired_caps:
platformName: Android
deviceName: 127.0.0.1:62001
appPackage: com.taobao.taobao
noReset: !!bool True
udid: 127.0.0.1:62001
appActivity: com.taobao.tao.welcome.Welcome

读yaml配置

1.读出来多个配置是list类型,desc是设备的描述,可以通过描述来找到对应的设备名称,如:雷电

2.返回desired_caps配置信息和port端口号,后面代码会用到

# coding=utf-8
from appium import webdriver
import time
import yaml
import os def get_desired_caps(devicesName='雷电'):
'''
从yaml读取desired_caps配置信息
参数name:设备名称,如:夜神/雷电
:return: desired_caps字典格式 和port
'''
curpath = os.path.dirname(os.path.realpath(__file__))
yamlpath = os.path.join(curpath, "taobao.yaml")
print("配置地址:%s" % yamlpath)
f = open(yamlpath, "r", encoding="utf-8")
a = f.read()
f.close()
# 把yaml文件转字典
d = yaml.load(a)
for i in d:
if devicesName in i["desc"]:
print(i)
# 启动服务
start_appium(port=i['port'])
return (i['desired_caps'], i['port'])

运行app代码

def run_app(devicesName):
# 配置参数
desired_caps = get_desired_caps(devicesName)
print(desired_caps) # 执行代码
driver = webdriver.Remote('http://127.0.0.1:%s/wd/hub' % desired_caps[1], desired_caps[0])
time.sleep(10)
# 点注册登陆
driver.find_element_by_xpath("//*[@text='注册/登录']").click()
time.sleep(6)
# content-desc
driver.find_element_by_xpath("//*[@text='请输入手机号码']").send_keys("15001234000")
driver.find_element_by_xpath("//*[@text='请输入验证码']").send_keys("1111")

python启动appium服务

1.如果嫌手工端口cmd窗口启动服务麻烦,可以用python去启动appium服务,释放你的双手

先判断服务启了没,没启动的话就执行cmd指令启动

# coding=utf-8
from appium import webdriver
import time
import yaml
import os
from tomorrow import threads # 作者:上海-悠悠 QQ交流群:330467341 def start_appium(port=4723, udid=""):
a = os.popen('netstat -ano | findstr "%s" '% port)
time.sleep(2)
t1 = a.read()
if "LISTENING" in t1:
print("appium服务已经启动:%s" % t1)
# s = t1.split(" ")
# s1 = [i for i in s if i != '']
# pip = s1[-1].replace("\n", "")
else:
# 启动appium服务
# appium -a 127.0.0.1 -p 4740 -U emulator-5554 127.0.0.1:62001 --no-reset
os.system("appium -a 127.0.0.1 -p %s -U %s --no-reset" % (port, udid))

多线程运行

1.多线程用一个很简单的tomorrow框架就行

# coding=utf-8
from appium import webdriver
import time
import yaml
import os
from tomorrow import threads # 作者:上海-悠悠 QQ交流群:330467341 def start_appium(port=4723, udid=""):
a = os.popen('netstat -ano | findstr "%s" '% port)
time.sleep(2)
t1 = a.read()
if "LISTENING" in t1:
print("appium服务已经启动:%s" % t1)
# s = t1.split(" ")
# s1 = [i for i in s if i != '']
# pip = s1[-1].replace("\n", "")
else:
# 启动appium服务
# appium -a 127.0.0.1 -p 4740 -U emulator-5554 127.0.0.1:62001 --no-reset
os.system("appium -a 127.0.0.1 -p %s -U %s --no-reset" % (port, udid)) def get_desired_caps(devicesName='雷电'):
'''
从yaml读取desired_caps配置信息
参数name:设备名称,如:夜神/雷电
:return: desired_caps字典格式
'''
curpath = os.path.dirname(os.path.realpath(__file__))
yamlpath = os.path.join(curpath, "taobao.yaml")
print("配置地址:%s" % yamlpath)
f = open(yamlpath, "r", encoding="utf-8")
a = f.read()
f.close()
# 把yaml文件转字典
d = yaml.load(a)
for i in d:
if devicesName in i["desc"]:
print(i)
# 启动服务
devicesName = i['desired_caps']['udid']
print(devicesName)
start_appium(port=i['port'], udid=devicesName)
return (i['desired_caps'], i['port']) @threads(2)
def run_app(devicesName):
# 配置参数
desired_caps = get_desired_caps(devicesName)
print(desired_caps) # 执行代码
driver = webdriver.Remote('http://127.0.0.1:%s/wd/hub' % desired_caps[1], desired_caps[0])
time.sleep(10)
# 点注册登陆
driver.find_element_by_xpath("//*[@text='注册/登录']").click()
time.sleep(6)
# content-desc
driver.find_element_by_xpath("//*[@text='请输入手机号码']").send_keys("15001234000")
driver.find_element_by_xpath("//*[@text='请输入验证码']").send_keys("1111") # driver.find_element_by_accessibility_id("帮助").click() if __name__ == "__main__":
# 作者:上海-悠悠 QQ交流群:330467341
devices = ["夜神", "雷电"]
for i in devices:
run_app(devicesName=i)

上海-悠悠 QQ交流群:330467341

appium+python自动化60-windows上同时启动多个appium服务,让多个android机器并行运行的更多相关文章

  1. Appium+python自动化20-查看iOS上app元素属性

    前言 学UI自动化首先就是定位页面元素,玩过android版的appium小伙伴应该都知道,appium的windows版自带的Inspector可以定位app上的元素 Mac版的appium1.6的 ...

  2. Appium+python自动化20-查看iOS上app元素属性【转载】

    前言 学UI自动化首先就是定位页面元素,玩过android版的appium小伙伴应该都知道,appium的windows版自带的Inspector可以定位app上的元素Mac版的appium1.6的版 ...

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

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

  4. Appium+python自动化8-Appium Python API

    Appium+python自动化8-AppiumPython API   前言: Appium Python API全集,不知道哪个大神整理的,这里贴出来分享给大家. 1.contexts conte ...

  5. Appium+python自动化-查看app元素属性

    本文转自:https://www.cnblogs.com/yoyoketang/p/7581831.html 前言 学UI自动化首先就是定位页面元素,玩过android版的appium小伙伴应该都知道 ...

  6. Appium+python自动化19-iOS模拟器(iOS Simulator)安装自家APP

    前言 做过iOS上app测试的小伙伴应该都知道,普通用户安装app都是从appstore下载安装,安装测试版本的app,一般就是开发给的二维码扫码安装, 或者开发给个.ipa的安装包文件,通过itoo ...

  7. Appium+python自动化19-iOS模拟器(iOS Simulator)安装自家APP【转载】

    前言 做过iOS上app测试的小伙伴应该都知道,普通用户安装app都是从appstore下载安装,安装测试版本的app,一般就是开发给的二维码扫码安装, 或者开发给个.ipa的安装包文件,通过itoo ...

  8. appium+python自动化61-中文输入乱码问题解决

    前言 在夜神模拟器上输入中文,发现是乱码,将unicodeKeyboard和resetKeyboard参数设置为True了,发现还是没法解决. 打开手机设置语言和输入法,发现找不到Appium And ...

  9. appium+python自动化50-生成定位对象模板templet(jinja2)

    前言 每次自己写pageobject定位元素对象太繁琐,格式都差不多,只是换个定位方法,这种就可以才有模板的方式,批量生成pageobject定位元素对象的模板 python里面生成模板有两个模块可以 ...

随机推荐

  1. npm install 装本地一直安装全局问题

    想用npm安装一些模块,不管怎么装,一直装作全局. 以为是node有问题,重装了N次,却还发现这个问题. 困惑几天无果, 偶然间通过此文章发现,npm存在配置文件:https://www.sitepo ...

  2. SG函数(转自百度百科)

    给定一个有向无环图和一个起始顶点上的一枚棋子,两名选手交替的将这枚棋子沿有向边进行移动,无法移 动者判负.事实上,这个游戏可以认为是所有Impartial Combinatorial Games的抽象 ...

  3. #ifndef的用法

    作用:防止头文件的重复包含和编译 定义 #ifndef x #define x ... #endif 这是宏定义的一种,它可以根据是否已经定义了一个变量来进行分支选择,一般用于调试等等.实际上确切的说 ...

  4. Go语言入门之指针的使用

    指针的使用: package main import "fmt" func zhi(){ a:= var b *int=&a //声明指针并赋值 *b=3 //改变内存地址 ...

  5. PHP完整的AES加解密算法使用及例子(256位)

    依赖PHP自身的mcrypt扩展 <?php class aes { // CRYPTO_CIPHER_BLOCK_SIZE 32 private $_secret_key = 'default ...

  6. [实战]MVC5+EF6+MySql企业网盘实战(18)——文件上传,下载,修改

    写在前面 经过一段时间的秀秀改改,终于把文件上传下载,修改文件夹文件名称的功能实现了. 系列文章 [EF]vs15+ef6+mysql code first方式 [实战]MVC5+EF6+MySql企 ...

  7. Codeforces Round #222 (Div. 1) 博弈 + dp

    一般这种要倒着来. #include<bits/stdc++.h> #define LL long long #define fi first #define se second #def ...

  8. bzoj 1452 二维树状数组

    #include<bits/stdc++.h> #define LL long long #define fi first #define se second #define mk mak ...

  9. Vuex总结

    Vuex官网链接:https://vuex.vuejs.org/zh-cn/strict.html Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式. 它采用集中式存储管理应用的所有组件 ...

  10. Spark 源码解析 : DAGScheduler中的DAG划分与提交

    一.Spark 运行架构 Spark 运行架构如下图: 各个RDD之间存在着依赖关系,这些依赖关系形成有向无环图DAG,DAGScheduler对这些依赖关系形成的DAG,进行Stage划分,划分的规 ...