目的:

  通过添加设备号,则自动给添加的设备分配端口,启动对应的appium服务。注意:为了方便,将共用一个配置文件。

1、公共的配置文件名称:desired_caps.yaml

platformVersion: 5.1.
platformName: Android
deviceName: oppo
appPackage: com.iBer.iBerAppV2
appActivity: com.iBer.iBerAppV2.MainActivity
#appPackage: com.android.mms
#appActivity: /com.qiku.android.mms.ui.MmsConversationListActivity
noReset: False
unicodeKeyborad: True #使用Unicode编码方式发送字符串
resetKeyborad: True #隐藏键盘
ip: 127.0.0.1
#port:
#devices_list: ["7f4bd69a",""] #给出需要启动的设备udid,此处启动2个真机
#devices_list: ["","127.0.0.1:62001"]
devices_list: [""]
phone: [""]

2、自动根据添加的设备分配端口,前提:检查当前分配的端口是否被占用,若已被占用则自动删除此端口的进程,重新分配此端口。文件名称:Check_port.py

# -*- coding: utf- -*-
'''
意义:端口的自动检测 '''
import socket
import os
import re def check_port(host,port):
'''检测端口是否可用''' s = socket.socket(socket.AF_INET,socket.SOCK_STREAM) #socket.SOCK_STREAM 或 SOCK_DGRAM
try:
s.connect((host,port))
s.shutdown() #禁止在一个socket上进行数据的接收与发送,利用shutdown函数使socket双向数据传输变为单向数据传输,
# shutdown需要一个单独的参数,该参数表示了如何关闭socket,:表示禁止将来读,:表示禁止将来写,:表示禁止将来读写 #except OSError as msg:
except:
print("port %s is avaliable")%port #端口可用
return True
else:
print ("port %s alreadly be in use !!!")%port #端口已被占用
return False def release_port(port):
print"release_port-------------杀掉已占用的端口"
'''杀掉正在执行的端口'''
cmd = "lsof -i:%s|awk 'NR==2{print $2}'" % port
pid = os.popen(cmd).read()
print "find port:%s, pid is value:%s" %(port,pid)
cmd = "kill -9 %s" % pid
print "kill port:%s,pid value:%s"%(port,pid)
os.popen(cmd).read() # if __name__ =="__main__":
# host = "127.0.0.1"
# port =
# check_port(host,port)
# release_port(port)

3、检查appium服务是否开启,根据当前连接的设备数量,自动开启对应的appium服务,文件名称为:muti_appium.py

# -*- coding: utf- -*-

'''
python启动多个appium服务----并发
'''
import subprocess
from time import ctime
import sys,os
import yaml reload(sys)
sys.setdefaultencoding('utf8') path = os.getcwd()
print path
with open(path+"/desired_caps.yaml","r") as file:
data = yaml.load(file)
devices_list = data["devices_list"] def appium_start(host,port):
print "-----------------------------appium_start-----------------------------"
'''启动appium服务'''
#此处的port+3是为了appium服务的启动端口不跟multi_device中的端口重复
bootstrap_port = str(port+)
print "bootstrap_port" + str(bootstrap_port)
'''# win
start /b appium -a 127.0.0.1 -p --log xxx.log --local-timezone
# mac
appium -a 127.0.0.1 -p --log xxx.log --local-timezone &'''
# cmd = "start /b appium -a"+host+" -p "+str(port)+" -bp "+str(bootstrap_port) windows上的写法
cmd = "appium -a " + host + " -p " + str(port) + " -bp " + str(bootstrap_port) print "%s at %s"%(cmd,ctime())
print path+'/appium_log/'+str(port)+'.log' logpath = os.getcwd()[:-]
print logpath
subprocess.Popen(cmd,shell=True,stdout=open(logpath+'/appium_log/'+str(port)+'.log','wa'),stderr=subprocess.STDOUT) # if __name__ == "__main__":
# host = "127.0.0.1"
# port =
# appium_start(host,port) # appium_process = [] lucky注销,释放开则是并发的启动appium服务
#
for i in range(len(devices_list)): #根据连接Android设备的数量,可更改此处的值
host = "127.0.0.1"
port = ++i
print port
appium_start(host, port) # appium = multiprocessing.Process(target=appium_start,args=(host,port))
# appium_process.append(appium) # if __name__ == "__main__": lucky注销
#
# for appium in appium_process:
# appium.start()
# for appium in appium_process:
# appium.join()

4、检查当前添加的设备号,自动开始执行多设备。文件名称为:muti_device.py

# -*- coding: utf- -*-

from appium import webdriver
from time import ctime
import yaml
import sys from Add_Case_Gather import Run_test
import os,time
from time import sleep
#为了读取yaml中的中文,否则会报错
reload(sys)
sys.setdefaultencoding('utf8') #获取desired_caps.yaml的存放路径
path = os.getcwd()
with open(path+"/desired_caps.yaml","r") as file:
data = yaml.load(file)
devices_list = data["devices_list"] #开始执行设备
for i in range(len(devices_list)):
port = + + i
def appium_desire(udid,port):
print "--------------------appium_desire-------------------------"
desired_caps = {}
desired_caps["platformName"] = data["platformName"]
desired_caps["platformVersion"] = data["platformVersion"]
desired_caps["deviceName"] = data["deviceName"]
desired_caps["udid"]=udid
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()))
print str(data['ip'])+str(port)
driver = webdriver.Remote('http://'+str(data['ip'])+':'+str(port)+'/wd/hub',desired_caps)
print driver #调用需要执行的步骤操作方法
Run_test(driver).run_test1() return devices_list[i],port

5、将如上的文件共同在一个文件中进行启动调用,文件名称为:Run_Test.py

# -*- coding: utf- -*-
'''并发的测试
主要功能:
、检查给定的端口是否被占用,如果占用则自动释放
、并发启动appium服务
、并发启动device服务
''' from Test.Common.multi_appium import appium_start
#from multi_device import appium_desire
from Test.Common.multi_device import appium_desire
from Test.Common.Check_port import *
from time import sleep
import multiprocessing
import sys
import yaml #为了读取yaml中的中文,否则会报错
reload(sys)
sys.setdefaultencoding('utf8') # 获取desired_caps.yam的路径
path = os.getcwd()
with open(path+"/desired_caps.yaml","r") as file:
data = yaml.load(file) devices_list = data["devices_list"] def start_appium_action(host,port):
print "start_appium_action------------------"
if check_port(host,port)==False:
release_port(port)
elif check_port(host,port)==True:
appium_start(host, port)
return True
else:
print("appium %s start faild!"%port)
return False def start_devices_action(udid,port):
host = "127.0.0.1"
appium_desire(udid, port) def appium_start_sync():
appium_process = []
for i in range(len(devices_list)):
host = "127.0.0.1"
port = ++i
appium = multiprocessing.Process(target=start_appium_action,args=(host,port))
appium_process.append(appium) for appium in appium_process:
appium.start()
for appium in appium_process:
appium.join() sleep() def devices_start_sync():
desired_process = []
for i in range(len(devices_list)):
port = ++i
desired = multiprocessing.Process(target=start_devices_action, args=(devices_list[i], port))
desired_process.append(desired) for desired in desired_process:
desired.start()
for desired in desired_process:
desired.join() if __name__ == "__main__":
appium_start_sync()
devices_start_sync()

如上已完成了多设备的添加,如果需要新增多个设备,则在desired_caps.yaml中的 devices_list: ["57614229"]中新增设备号,然后运行Run_Test.py即可。

appium+python 【Mac】UI自动化测试封装框架介绍 <五>---脚本编写(多设备)的更多相关文章

  1. appium+python 【Mac】UI自动化测试封装框架介绍 <七>---脚本编写规范

    脚本的使用,注释非常关键,无论自己的后期查看还是别人使用,都可以通过注释很明确的知道代码所表达的意思,明确的知道如何调用方法等等.每个团队均有不同的商定形式来写脚本,因此没有明确的要求和规范来约束.如 ...

  2. appium+python 【Mac】UI自动化测试封装框架介绍 <二>---脚本编写(单设备)

    1.单设备的执行很简单,平时可多见的是直接在config中进行配置并进行运行即可.如下: # coding=UTF- ''' Created on // @author: SYW ''' from T ...

  3. appium+python 【Mac】UI自动化测试封装框架介绍 <三>---脚本的执行

    我自己编写的脚本框架中,所有的脚本执行均放在一个py文件中,此文件作为启动文件执行,包含了运行此文件将执行脚本.分配设备端口.自启appium服务等. 详细的介绍待后期补充.

  4. appium+python 【Mac】UI自动化测试封装框架介绍 <四>---脚本的调试

    优秀的脚本调试定位问题具备的特点: 1.方便调试. 2.运行报错后容易定位出现的问题. 3.日志的记录清晰 4.日志可被存储,一般测试结果的分析在测试之后会进行,那么日志的存储将会为后期的分析问题带来 ...

  5. appium+python 【Mac】UI自动化测试封装框架流程简介 <一>

    为了多人之间更方便的协作,那么框架本身的结构和编写方式将变得很重要,因此每个团队都有适合自己的框架.如下本人对APP的UI自动化测试的框架进行进行了简单的汇总.主要目的是为了让团队中的其余人员接手写脚 ...

  6. Python爬虫教程-30-Scrapy 爬虫框架介绍

    从本篇开始学习 Scrapy 爬虫框架 Python爬虫教程-30-Scrapy 爬虫框架介绍 框架:框架就是对于相同的相似的部分,代码做到不出错,而我们就可以将注意力放到我们自己的部分了 常见爬虫框 ...

  7. 使用appium+python做UI自动化的demo

    使用appium+python做UI自动化的demo 案例使用的知乎app,下载最新的知乎apk,存在了电脑上,只需要配置本机上app目录,不需要再配置appPackage和appActivity # ...

  8. Appium+python移动端自动化测试-python库及pycharm安装(二)

    一.安装python库 安装python库有很多种方法,如pip安装.源文件安装.运行包安装,但我们最常用的就是使用pip进行安装 Appium+python做移动端的自动化测试,所需要安装以下pyt ...

  9. 基于python+appium+yaml安卓UI自动化测试分享

    结构介绍 之前分享过一篇安卓UI测试,但是没有实现数据与代码分离,后期维护成本较高,所以最近抽空优化了一下.不想看文章得可以直接去Github,欢迎拍砖大致结构如下:   结构.png testyam ...

随机推荐

  1. TCP 客户端编程

    1.Qt中TCP客户端编程 对Qt编程而言,网络只是数据传输的通道: Qt提供了QTcpSocket类(封装了TCP协议细节): 将QTcpSocket的对象当做黑盒使用,进行数据首发. 1.1QTc ...

  2. 【leetcode算法-简单】35. 搜索插入位置

    [题目描述] 给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引.如果目标值不存在于数组中,返回它将会被按顺序插入的位置. 你可以假设数组中无重复元素. 示例 1: 输入: [1,3,5, ...

  3. 【贪心】洛谷2019 OI春令营 - 普及组 作业

    [P3817 小A的糖果 小A有N个糖果盒,第i个盒中有a[i]颗糖果. 小A每次可以从其中一盒糖果中吃掉一颗,他想知道,要让任意两个相邻的盒子中加起来都只有x颗或以下的糖果,至少得吃掉几颗糖. [贪 ...

  4. Python3 使用pygal 生成世界人口地图

    最近在看<python从入门到实践>,其中有一个例子是使用pygal制作世界人口地图,觉得挺有意思的,这里就记录下来了, 其实代码不是很复杂,使用环境环境python3.废话不多说,直接上 ...

  5. BZOJ3998 TJOI2015弦论(后缀自动机)

    先考虑相同子串视为一个.按SAM的拓扑序预处理出从每个节点开始能得到多少个本质不同子串(注意虽然一个节点对应多个子串,但到达该点时当前的子串显然是确定为其中一个的),然后按位贪心即可. 相同子串视为多 ...

  6. 线段树 面积并问题 hdu 1255 1542

    重点整理面积并的思想 以及PushUp的及时更新 还有就是cover的实现 以及建树每个节点存的信息(每个节点存的是一个线段的信息) http://www.tuicool.com/articles/6 ...

  7. Java Web 深入分析(8) Servlet工作原理解析

    Servlet Servlet(Server Applet)是Java Servlet的简称,称为小服务程序或服务连接器,用Java编写的服务器端程序,主要功能在于交互式地浏览和修改数据,生成动态We ...

  8. 【es6】将2个数组合并为一个数组

    //第一种 一个数组中的值为key 一个数组中的值为value let arr1 = ['内存','颜色','尺寸']; let arr2 = [1,2,3]; let temp = arr1.map ...

  9. default(Nullable(type)) vs default(type)

    default(Nullable<long>) == null default(long?) == null default(long) == 0L

  10. friend

    #include <iostream> using namespace std; //friend 友元,效率的问题 //get 方法和set方法,是标准封装的结果,friend破坏了这种 ...