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.希望大家在看完帖子后可以留下你的意见,感谢!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值