appiumpython框架实例_Appium+python 框架 (二)
前言
之前已經(jīng)發(fā)過一個,許多人給提了很寶貴的意見,根據(jù)大家的意見和自己的一點思考,對原來的框架進(jìn)行了一點修改,這里給大家分享一下,還是請各位看完后多多提意見。
結(jié)構(gòu)
大體的結(jié)構(gòu)沒有太大的變化,這里附上原帖地址 https://testerhome.com/topics/3460
修改的地方有以下幾個:
1.在testSet下增加了一個bsns文件夾,里面有bsnsCommon.py;element.xml;TestCase.xls3個文件夾
2.common里面增加AppiumServer.py;將myPhone.py變?yōu)閕nit.py
3.增加了autoRun.bat和install.bat
修改處
1.講AppiumServer從run.py中抽離出來,封裝成了AppiumServer.py
2.棄用自己寫的Log方法,使用了python自帶的logging
3.講element的路徑配置進(jìn)了element.xml中
4.實現(xiàn)了測試數(shù)據(jù)參數(shù)化
5.做成了bat文件調(diào)用run.py
6.修改了注釋風(fēng)格
下面仔細(xì)說一下
AppiumServer
這個借鑒了cosyman以前發(fā)過的帖子,原帖地址 https://testerhome.com/topics/1864
總結(jié)而言就是原先用線程做的現(xiàn)在改成了進(jìn)程。代碼如下:
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方法,現(xiàn)在是使用了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標(biāo)簽外面添加了一個activity標(biāo)簽,這樣就可以不必要同個標(biāo)簽配置多次了。
Welcome
RelativeLayout
ID
ag_ll_dotlayout
2.調(diào)用方法
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
根據(jù)anctivityName 和 elementName獲取element,使用的時候可以這樣用:element(anctivityName ,elementName).click()
測試數(shù)據(jù)參數(shù)化
這里我是使用了ParamUnittest,官網(wǎng)地址如下大家可以咨詢下載:https://pypi.python.org/pypi/ParamUnittest#downloads
將測試數(shù)據(jù)配置到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的例官網(wǎng)里面有好多,大家可以自己去研究。
bat
本來是想在bat文件里面開啟server,識別安裝軟件,后來發(fā)現(xiàn)自己的能力有限,要考慮的東西有點多,后來放棄了,改在py文件里面完成,然后僅在bat文件里面調(diào)用。
ECHO START INSTALL
F:
cd F:\testApp01
start pythonw testSet\init.py
ECHO END INSTALL
PAUSE
總結(jié)
1.生成的報告不太滿意,目前還是自己實現(xiàn)的,不知道各位有什么好的推薦?
2.異常機(jī)制依舊沒有完善的太好,繼續(xù)努力。
3.論壇里面有太多好帖子了,感覺大神的分享。
4.希望大家在看完帖子后可以留下你的意見,感謝!!!
總結(jié)
以上是生活随笔為你收集整理的appiumpython框架实例_Appium+python 框架 (二)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 对的调用没有匹配的函数_前端开发之——函
- 下一篇: 表单如何添加大的文本框_在 Flutte