appiumpython框架实例_Appium+python 框架 (二)
前言
之前已经发过一个,许多人给提了很宝贵的意见,根据大家的意见和自己的一点思考,对原来的框架进行了一点修改,这里给大家分享一下,还是请各位看完后多多提意见。
结构
大体的结构没有太大的变化,这里附上原帖地址 https://testerhome.com/topics/3460
修改的地方有以下几个:
1.在testSet下增加了一个bsns文件夹,里面有bsnsCommon.py;element.xml;TestCase.xls3个文件夹
2.common里面增加AppiumServer.py;将myPhone.py变为init.py
3.增加了autoRun.bat和install.bat
修改处
1.讲AppiumServer从run.py中抽离出来,封装成了AppiumServer.py
2.弃用自己写的Log方法,使用了python自带的logging
3.讲element的路径配置进了element.xml中
4.实现了测试数据参数化
5.做成了bat文件调用run.py
6.修改了注释风格
下面仔细说一下
AppiumServer
这个借鉴了cosyman以前发过的帖子,原帖地址 https://testerhome.com/topics/1864
总结而言就是原先用线程做的现在改成了进程。代码如下:
class AppiumServer:
def __init__(self):
global appiumPath, baseUrl
appiumPath = readConfigLocal.getConfigValue("appiumPath")
baseUrl = readConfigLocal.getConfigValue("baseUrl")
def startServer(self):
"""start the appium server
:return:
"""
cmd = self.getCmd()
t1 = runServer(cmd)
p = Process(target=t1.start())
p.start()
def stopServer(self):
"""stop the appium server
:return:
"""
#kill myServer
os.system('taskkill /f /im node.exe')
def reStartServer(self):
"""reStart the appium server
:arg:
:return:
"""
self.stopServer()
self.startServer()
def isRunnnig(self):
"""Determine whether server is running
:return:True or False
"""
response = None
url = baseUrl+"/status"
try:
response = urllib.request.urlopen(url, timeout=5)
if str(response.getcode()).startswith("2"):
return True
else:
return False
except URLError:
return False
finally:
if response:
response.close()
def getCmd(self):
"""get the cmd of start appium server
:return:cmd
"""
rootDirectory = appiumPath[:2]
startCMD = "node node_modules\\appium\\bin\\appium.js"
cmd =rootDirectory+"&"+"cd "+appiumPath+"&"+startCMD
return cmd
import threading
class runServer(threading.Thread):
def __init__(self, cmd):
threading.Thread.__init__(self)
self.cmd = cmd
def run(self):
os.system(self.cmd)
if __name__ == "__main__":
oo = AppiumServer()
oo.startServer()
Log
原先是自己写的log方法,现在是使用了python自带的logging,部分代码如下:
self.logger = logging.getLogger()
self.logger.setLevel(logging.INFO)
#create handler,write log
fh = logging.FileHandler(os.path.join(logPath, "outPut.log" ))
#Define the output format of formatter handler
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
fh.setFormatter(formatter)
self.logger.addHandler(fh)
这里我并没有使用logging的配置文件,而是直接写在的代码中
element.xml
这里也是借鉴了xushizhao的帖子,原帖地址如下 https://testerhome.com/topics/2937
为什么要这样做我就不多说,原帖里都说了,代码如下:
1.element.xml
与原帖不同的是我在element标签外面添加了一个activity标签,这样就可以不必要同个标签配置多次了。
Welcome
RelativeLayout
ID
ag_ll_dotlayout
2.调用方法
activity = {}
def setXml():
"""
get the xml file's value
:use:
a = getXml(path)
print(a.get(".module.GuideActivity").get("skip").get("type"))
:param: xmlPath
:return:activity
"""
if len(activity) == 0:
xmlPath = os.path.join(readConfig.prjDir, "testSet\\bsns", "element.xml")
# open the xml file
per = ET.parse(xmlPath)
allElement = per.findall('activity')
for firstElement in allElement:
activityName = firstElement.get("name")
element = {}
for secondElement in firstElement.getchildren():
elementName = secondElement.get("name")
elementChild = {}
for thirdElement in secondElement.getchildren():
elementChild[thirdElement.tag] = thirdElement.text
element[elementName] = elementChild
activity[activityName] = element
def getElDict(activityName, elementName):
"""
According to the activityName and elementName get element
:param activityNmae:
:param elementName:
:return:
"""
setXml()
elementDict = activity.get(activityName).get(elementName)
return elementDict
class element:
def __init__(self, activutyName, elementName):
global driver
driver = myDriver.GetDriver()
self.activutyNmae = activutyNmae
self.elementName = elementName
elementDict = getElDict(self.activutyNmae, self.elementName)
self.pathtype = elementDict.get("pathtype")
self.pathvalue = elementDict.get("pathvalue")
def isExist(self):
"""
To determine whether an element is exits
:return: TRUE or FALSE
"""
try:
if self.pathtype == "ID":
driver.find_element_by_id(self.pathvalue)
if self.pathtype == "CLASSNAME":
driver.find_element_by_class_name(self.pathvalue)
if self.pathtype == "XPATH":
driver.find_element_by_xpath(self.pathvalue)
if self.pathtype == "NAME":
driver.find_element_by_name(self.pathvalue)
except NoSuchElementException:
return False
return True
def doesExist(self):
"""
To determine whether an element is exits
:return:
"""
i = 1
while not self.isExist():
sleep(1)
i = i+1
if i >= 10:
return False
else:
return True
def get(self):
"""
get one element
:return:
"""
if self.doesExist():
if self.pathtype == "ID":
element = driver.find_element_by_id(self.pathvalue)
return element
if self.pathtype == "CLASSNAME":
element = driver.find_element_by_class_name(self.pathvalue)
return element
if self.pathtype == "XPATH":
element = driver.find_element_by_xpath(self.pathvalue)
return element
if self.pathtype == "NAME":
element = driver.find_element_by_name(self.pathvalue)
return element
else:
return None
def gets(self, index):
"""
get one element in elementList
:return:
"""
if self.doesExist():
if self.pathtype == "ID":
elements = driver.find_elements_by_id(self.pathvalue)
return elements[index]
if self.pathtype == "CLASSNAME":
elements = driver.find_elements_by_class_name(self.pathvalue)
return elements[index]
if self.pathtype == "XPATH":
elements = driver.find_elements_by_xpath(self.pathvalue)
return elements[index]
if self.pathtype == "NAME":
elements = driver.find_elements_by_name(self.pathvalue)
return elements[index]
return None
else:
return None
def click(self):
"""
click element
:return:
"""
try:
el = self.get()
el.click()
except AttributeError:
raise
def clicks(self, index):
"""
click element
:return:
"""
try:
el = self.gets(index)
el.click()
except AttributeError:
raise
def sendKey(self,values):
"""
input the key
:return:
"""
try:
el = self.get()
el.clear()
el.send_keys(values)
except AttributeError:
raise
def sendKeys(self, index, values):
"""
input the key
:return:
"""
try:
el = self.gets(index)
el.clear()
el.send_keys(values)
except AttributeError:
raise
def getAttribute(self, attribute):
"""
get the element attribute
:param attribute:
:return:value
"""
el = self.get()
value = el.get_attribute(attribute)
return value
根据anctivityName 和 elementName获取element,使用的时候可以这样用:element(anctivityName ,elementName).click()
测试数据参数化
这里我是使用了ParamUnittest,官网地址如下大家可以咨询下载:https://pypi.python.org/pypi/ParamUnittest#downloads
将测试数据配置到excel里面,然后读取。代码如下:
读取excel
import xlrd
cls = []
def getXLS(sheetName):
"""
get the value in excel
:param sheetName
:return:cls
"""
if len(cls) == 0:
xlsPath = os.path.join(readConfig.prjDir, "testSet\\bsns", "TestCase.xls")
#read the excel
data = xlrd.open_workbook(xlsPath)
#get the sheet
table = data.sheet_by_name(sheetName)
nrows = table.nrows
for i in range(nrows):
if table.row_values(i)[0] != 'userName':
cls.append(table.row_values(i))
return cls
ParamUnittest的使用
loginCls = getLoginCls()
@paramunittest.parametrized(
*loginCls
)
class TestBar(paramunittest.ParametrizedTestCase):
def setParameters(self, userName,password,result):
self.userName = userName
self.password = password
self.result = result
def runTest(self):
print(self.userName, self.password, self.result)
ParamUnittest的例官网里面有好多,大家可以自己去研究。
bat
本来是想在bat文件里面开启server,识别安装软件,后来发现自己的能力有限,要考虑的东西有点多,后来放弃了,改在py文件里面完成,然后仅在bat文件里面调用。
ECHO START INSTALL
F:
cd F:\testApp01
start pythonw testSet\init.py
ECHO END INSTALL
PAUSE
总结
1.生成的报告不太满意,目前还是自己实现的,不知道各位有什么好的推荐?
2.异常机制依旧没有完善的太好,继续努力。
3.论坛里面有太多好帖子了,感觉大神的分享。
4.希望大家在看完帖子后可以留下你的意见,感谢!!!
appiumpython框架实例_Appium+python 框架 (二)相关推荐
- java mina框架实例_Apache Mina框架实践
1.为什么要用Apache Mina框架 ApacheMina Server 是一个网络通信应用框架,Mina 可以帮助我们快速开发高性能.高扩展性的网络通信应用,Mina 提供了事件驱动.异步(Mi ...
- python支持向量机框架_Netflix 内部 Python 框架 Metaflow 正式开源,可加速机器学习模型部署...
近日,美国视频流媒体平台及视频出版制作公司 Netflix 网飞的数据科学团队宣布正式开源其 Python 库 Metaflow,以帮助更多数据科学家与工程师构建.管理相关的数据科学项目. Metaf ...
- appium python实例_Appium Python 常用元素定位方法测试小米计算器实例
常用的元素定位方法 Uiautomator 定位 image.png text属性的方法 #text driver.find_element_by_android_uiautomator('new U ...
- python爬虫框架排行榜-哪种Python框架适合你?简单介绍几种主流Python框架
众所周知,Python开发框架大大减少了开发者不必要的重复劳动,提高了项目开发效率的同时,还使得创建的程序更加稳定.目前比较主流的Python框架都有哪些呢?一般大家用的比较多的是Django.Fla ...
- python框架大全_常用的Python开源框架有哪些?列举这3个
随着人工智能快速发展,不仅在各个领域应用日益广泛,同时也引发了教学内容的变革和创新.人工智能的火热得益于成功的开源以及深度学习框架的不断涌现.而Python作为一种脚本语言,具有易学.易维护等优点,它 ...
- 二、python框架相关知识体系
Django框架 1.django框架.flask框架和Tornado框架的区别? django框架,内置组件多,自身功能强大,是一个大而全的框架,ORM.Admin.中间件.Form.ModelFr ...
- python app自动化测试框架_appium+python,app自动化测试框架
基于appium的app自动化测试框架 基于appium框架的app自动化测试 App自动化测试主要难点在于环境的搭建,appium完全是基于selenium进行的扩展,所以app测试框架也是基于we ...
- python 写csv scrapy_scrapy爬虫框架实例一,爬取自己博客
本篇就是利用scrapy框架来抓取本人的博客,博客地址:http://www.cnblogs.com/shaosks scrapy框架是个比较简单易用基于python的爬虫框架,相关文档:http:/ ...
- HTML学习笔记之框架实例(二)
2. 框架实例 2.1.垂直框架: 尺寸可调整(鼠标放置在相交处) cols 标签 <html> <!--垂直框架cols--> <frameset cols=" ...
最新文章
- Wireshark默认不抓取本地包的解决方式
- Windows Phone 7 开发 31 日谈——第6日:工具栏
- Docker 镜像之存储管理
- 【哲学探讨】娱乐至死
- vc--少林72般绝技
- 彻底搞定C指针-——第五篇:函数参数的传递
- Flume监听端口,输出端口数据案例
- Guava事件处理组件Eventbus使用入门
- final、finally 和 finalize的区别
- 2019医学电子书下载PDF电子版下载
- ansys linux17.2 字体,ubuntu16.04安装Ansys17.2教程,及遇到的问题(安装非完美)
- 从留言板开始做网站(三)——CSS样式代码
- 如何编写DTD文档类型定义
- Vue Events模块原理分析
- Linux下Chelsio T5调试方法
- ai如何做倒角和圆角_在ai中怎么用小白工具把矩形的直角改成圆角?,你值得一看的技巧...
- 中集集团高科技企业中集飞瞳,贯彻国家人工智能与实体经济深度融合战略,成熟AI产品智能航运智能化港航智慧港口智能铁路智能多式联运
- ubuntu 8.10安装配置经验(Intrepid Ibex)——转载
- CVPR 2023 论文分类汇总:一个专为计算机视觉领域研究者打造的学术资源宝库
- 基于8051的电子密码锁程序
热门文章
- request对象_java学习之web基础(2):Request
- python字典值的和计算_第一章Python数据结构和算法(字典的运算)
- .net core 发起web请求_温故知新 .Net重定向深度分析
- c++读取图片_Pytorch读取,加载图像数据(一)
- html lt;ligt; 属性,HTML文件中lt;HRgt;标签各个属性的作用是什么?
- orcle 删除表报正在使用_oracle 删除表空间错误 提示:ora-02429:无法删除用于强制唯一/...
- 浅谈分库分表那些事儿
- 这 10 道 Java 测试题,据说阿里 P7 的正确率只有 50%
- 计算机如何“看懂”图片?达摩院提出新的研究方法
- 一个菜鸟程序员的游戏开发心得