前言

之前已经发过一个,许多人给提了很宝贵的意见,根据大家的意见和自己的一点思考,对原来的框架进行了一点修改,这里给大家分享一下,还是请各位看完后多多提意见。

结构

大体的结构没有太大的变化,这里附上原帖地址 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 框架 (二)相关推荐

  1. java mina框架实例_Apache Mina框架实践

    1.为什么要用Apache Mina框架 ApacheMina Server 是一个网络通信应用框架,Mina 可以帮助我们快速开发高性能.高扩展性的网络通信应用,Mina 提供了事件驱动.异步(Mi ...

  2. python支持向量机框架_Netflix 内部 Python 框架 Metaflow 正式开源,可加速机器学习模型部署...

    近日,美国视频流媒体平台及视频出版制作公司 Netflix 网飞的数据科学团队宣布正式开源其 Python 库 Metaflow,以帮助更多数据科学家与工程师构建.管理相关的数据科学项目. Metaf ...

  3. appium python实例_Appium Python 常用元素定位方法测试小米计算器实例

    常用的元素定位方法 Uiautomator 定位 image.png text属性的方法 #text driver.find_element_by_android_uiautomator('new U ...

  4. python爬虫框架排行榜-哪种Python框架适合你?简单介绍几种主流Python框架

    众所周知,Python开发框架大大减少了开发者不必要的重复劳动,提高了项目开发效率的同时,还使得创建的程序更加稳定.目前比较主流的Python框架都有哪些呢?一般大家用的比较多的是Django.Fla ...

  5. python框架大全_常用的Python开源框架有哪些?列举这3个

    随着人工智能快速发展,不仅在各个领域应用日益广泛,同时也引发了教学内容的变革和创新.人工智能的火热得益于成功的开源以及深度学习框架的不断涌现.而Python作为一种脚本语言,具有易学.易维护等优点,它 ...

  6. 二、python框架相关知识体系

    Django框架 1.django框架.flask框架和Tornado框架的区别? django框架,内置组件多,自身功能强大,是一个大而全的框架,ORM.Admin.中间件.Form.ModelFr ...

  7. python app自动化测试框架_appium+python,app自动化测试框架

    基于appium的app自动化测试框架 基于appium框架的app自动化测试 App自动化测试主要难点在于环境的搭建,appium完全是基于selenium进行的扩展,所以app测试框架也是基于we ...

  8. python 写csv scrapy_scrapy爬虫框架实例一,爬取自己博客

    本篇就是利用scrapy框架来抓取本人的博客,博客地址:http://www.cnblogs.com/shaosks scrapy框架是个比较简单易用基于python的爬虫框架,相关文档:http:/ ...

  9. HTML学习笔记之框架实例(二)

    2. 框架实例 2.1.垂直框架: 尺寸可调整(鼠标放置在相交处) cols 标签 <html> <!--垂直框架cols--> <frameset cols=" ...

最新文章

  1. Wireshark默认不抓取本地包的解决方式
  2. Windows Phone 7 开发 31 日谈——第6日:工具栏
  3. Docker 镜像之存储管理
  4. 【哲学探讨】娱乐至死
  5. vc--少林72般绝技
  6. 彻底搞定C指针-——第五篇:函数参数的传递
  7. Flume监听端口,输出端口数据案例
  8. Guava事件处理组件Eventbus使用入门
  9. final、finally 和 finalize的区别
  10. 2019医学电子书下载PDF电子版下载
  11. ansys linux17.2 字体,ubuntu16.04安装Ansys17.2教程,及遇到的问题(安装非完美)
  12. 从留言板开始做网站(三)——CSS样式代码
  13. 如何编写DTD文档类型定义
  14. Vue Events模块原理分析
  15. Linux下Chelsio T5调试方法
  16. ai如何做倒角和圆角_在ai中怎么用小白工具把矩形的直角改成圆角?,你值得一看的技巧...
  17. 中集集团高科技企业中集飞瞳,贯彻国家人工智能与实体经济深度融合战略,成熟AI产品智能航运智能化港航智慧港口智能铁路智能多式联运
  18. ubuntu 8.10安装配置经验(Intrepid Ibex)——转载
  19. CVPR 2023 论文分类汇总:一个专为计算机视觉领域研究者打造的学术资源宝库
  20. 基于8051的电子密码锁程序

热门文章

  1. request对象_java学习之web基础(2):Request
  2. python字典值的和计算_第一章Python数据结构和算法(字典的运算)
  3. .net core 发起web请求_温故知新 .Net重定向深度分析
  4. c++读取图片_Pytorch读取,加载图像数据(一)
  5. html lt;ligt; 属性,HTML文件中lt;HRgt;标签各个属性的作用是什么?
  6. orcle 删除表报正在使用_oracle 删除表空间错误 提示:ora-02429:无法删除用于强制唯一/...
  7. 浅谈分库分表那些事儿
  8. 这 10 道 Java 测试题,据说阿里 P7 的正确率只有 50%
  9. 计算机如何“看懂”图片?达摩院提出新的研究方法
  10. 一个菜鸟程序员的游戏开发心得