启动多个appium服务(同时运行多台设备)
准备:
一台真机一台模拟器(使用的是“夜神模拟器”)
先查看是否检测到设备 adb devices
由上图可看出没有检测到模拟器(夜神模拟器已开启)
可通过以下配置完成:
第一步:找到adb的安装路径,找到adb.exe
第二步:将adb.exe复制到夜神模拟器下安装路径下的bin,更改名称为 nox_adb.exe;
因为夜神模拟器的安装路径下已经有相同名字的文件,复制粘贴前请做好区分,如下图可先将之前的nox_adb.exe 加了_1做区分;adb.exe也一样需要做区分(或者提前改好adb.exe的名称)
再次adb devices时,可检测到模拟器
但是连接上真机的时候,又只检测到真机,不连接真机也没有检查到模拟器
这时候执行命令:adb connect 127.0.0.1:62001
能检测到模拟器,再连接上真机后,真机和模拟器都能检测到
启动多个appium服务
前提:已安装yaml 模块(pip install pyyaml )和 tomorrow框架 (pip install tomorrow)
1.启动appium服务,可以用命令行模式
比如
第一个appium服务,可以指定一个端口 -p 4723,然后指定一个设备名称 -u 【真机】,也就是-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
def start_appium(port, bootstrap, 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("start /b appium -a 127.0.0.1 -p %s -U %s --no-reset" % (port, udid)) # appium -a 127.0.0.1 -p 4724 -bp 4725 -U 127.0.0.1:62001 os.system("start /b appium -a 127.0.0.1 -p %s -bp %s -U %s" % (port, bootstrap, udid)) def stop_appium(): # 关闭所有的appium进程 os.system("start /b taskkill /F /t /IM node.exe")
2.
A.运行不同手机时候,desired_caps的参数配置肯定也是需要多个的,用yaml文件可以管理多个desired_caps配置,方便查看
B.yaml文件配置
pycharm新建一个文件,名称以 .yaml结尾即可
- desc: 设备名称_真机1,appium启动服务端口号_4723 port: 4723 desired_caps: platformName: Android deviceName: ML5RRPCUWO appPackage: com.zhijiepay.android noReset: !!bool True platformVersion: 5.1.1 udid: ML5RRPCUWO appActivity: .ui.login.ui.Splash_Activity newCommandTimeout: 120 bootstrap-port: 4726 - desc: 设备名称_夜神,appium启动服务端口号_4724 port: 4724 desired_caps: platformName: Android deviceName: 127.0.0.1:62001 appPackage: com.zhijiepay.android noReset: !!bool True platformVersion: 4.4.2 udid: 127.0.0.1:62001 appActivity: .ui.login.ui.Splash_Activity newCommandTimeout: 120 bootstrap-port: 4725
C.
读yaml配置
1).读出来多个配置是list类型,desc是设备的描述,可以通过描述来找到对应的设备名称,如:真机1
2).返回desired_caps配置信息和port端口号以及bootstrap-port
def get_desired_caps(devices_name): """ 从yaml读取desired_caps配置信息 参数name:设备名称,如:夜神/真机 :return: desired_caps字典格式 """ # curpath = os.path.dirname(os.path.realpath(__file__)) yamlpath = os.path.join(yaml_path, "yaml_appium.yaml") print("配置地址:%s" % yamlpath) f = open(yamlpath, "r", encoding="utf-8") a = f.read() f.close() # 把yaml文件转字典 d = yaml.load(a) for ii in d: if devices_name in ii["desc"]: # 判断输入的设备名称是否存在 print(ii) # 启动服务 devicesname = ii['desired_caps']['udid'] print("devicesName: %s" % devicesname) # print("port: %s" %ii['port']) start_appium(port=ii['port'], bootstrap=ii['bootstrap-port'], udid=ii['desired_caps']['udid']) # start_appium(port=ii['port'], udid=devicesName) return ii['desired_caps'], ii['port']
完整代码如下:
# coding=utf-8 from appium import webdriver import time import yaml import os from tomorrow import threads from src.pages import login_page from config.globalparameter import login_name, login_password, yaml_path def start_appium(port, bootstrap, 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("start /b appium -a 127.0.0.1 -p %s -U %s --no-reset" % (port, udid)) # appium -a 127.0.0.1 -p 4724 -bp 4725 -U 127.0.0.1:62001 os.system("start /b appium -a 127.0.0.1 -p %s -bp %s -U %s" % (port, bootstrap, udid)) def stop_appium(): # 关闭所有的appium进程 os.system("start /b taskkill /F /t /IM node.exe") def get_desired_caps(devices_name): """ 从yaml读取desired_caps配置信息 参数name:设备名称,如:夜神/真机1 :return: desired_caps字典格式 """ # curpath = os.path.dirname(os.path.realpath(__file__))
yamlpath = os.path.join(yaml_path, "yaml_appium.yaml") print("配置地址:%s" % yamlpath) f = open(yamlpath, "r", encoding="utf-8") a = f.read() f.close() # 把yaml文件转字典 d = yaml.load(a) for ii in d: if devices_name in ii["desc"]: # 判断输入的设备名称是否存在 print(ii) # 启动服务 devicesname = ii['desired_caps']['udid'] print("devicesName: %s" % devicesname) # print("port: %s" %ii['port']) start_appium(port=ii['port'], bootstrap=ii['bootstrap-port'], udid=ii['desired_caps']['udid']) # start_appium(port=ii['port'], udid=devicesName) return ii['desired_caps'], ii['port'] @threads(2) def run_app(devices_name): # 配置参数 desired_caps = get_desired_caps(devices_name) print(desired_caps) print(desired_caps[1]) # 执行代码 driver = webdriver.Remote('http://127.0.0.1:%s/wd/hub' % desired_caps[1], desired_caps[0]) # desired_caps[1]表示端口号。 desired_caps[0]表示设备信息 time.sleep(5) login_page1 = login_page.login_page(driver) login_page1.input_user(login_name) login_page1.input_Pws(login_password) login_page1.click_btnLogin() # self.driver.find_element_by_id('com.zhijiepay.android:id/but_OK').click() # 设置隐式等待时间 driver.implicitly_wait(3) time.sleep(5) if __name__ == "__main__": devices = ["夜神", "真机1"] for i in devices: run_app(devices_name=i) stop_appium()