1、新建一個包名:common(用于存放基本函數封裝)
(1)在common包下新建一個base.py文件,作用:頁面操作封裝。base.py文件代碼如下:
#coding=utf-8"""------------------------------------@Time:2020/01/15@Auth:Anker@File:base.py@Description:頁面操作封裝@IDE:PyCharm@Motto:Believeinyourselfandpersistencecanmakesuccess!------------------------------------"""fromselenium.webdriver.support.waitimportWebDriverWaitfromconfig.read_configimportReadConfclassBasePage(object):#讀取config.ini配置文件,傳入sections值url=ReadConf()#傳入sections模塊standard_url=url.readConf("sections")#這里傳入sections模塊中的urlbase_url=standard_url['url']def__init__(self,driver,test_url=base_url):"""構造函數:paramdriver:param傳入url"""self.driver=driverself.url=test_url#設置全局元素隱式等待時間為10秒鐘self.driver.implicitly_wait(10)defopen_url(self):"""打開url:param:"""url=self.urlself.driver.get(url)title=self.driver.titleprint("項目名稱:",title+"2.6")print("項目地址:",self.driver.current_url)defback(self):"""瀏覽器后退按鈕:param:"""self.driver.back()defforward(self):"""瀏覽器前進按鈕:param:"""self.driver.forward()defclose(self):"""關閉并停止瀏覽器服務:param:"""self.driver.quit()deffind_element(self,*loc):"""判斷定位方式(常見的有8種獲取元素的方法):param*loc"""try:WebDriverWait(self.driver,20).until(lambdadriver:driver.find_element(*loc).is_displayed())returnself.driver.find_element(*loc)except:print("元素在頁面中未找到!",*loc)deffind_elements(self,*loc):returnself.driver.find_elements(*loc)definput_content(self,loc,content):"""文本框內容輸入:paramloc:paramcontent"""self.find_element(*loc).send_keys(content)defsend_keys(self,loc,value,clear_first=True,click_first=True):try:#getattr相當于self.locloc=getattr(self,"_%s"%loc)ifclick_first:self.mouse_click(loc)#調用鼠標點擊事件方法ifclear_first:self.mouse_clear(loc)#調用鼠標清理事件方法self.find_element(*loc).send_keys(value)exceptArithmeticError:print(u"%s頁面中未能找到%s元素"%(self,loc))defmouse_clear(self,loc):"""鼠標清理事件:paramloc"""returnself.find_element(*loc).clear()defmouse_click(self,loc):"""鼠標點擊事件:paramloc"""returnself.find_element(*loc).click()defscript(self,src):returnself.driver.execute_script(src)defswitch_frame(self,loc):returnself.driver.switch_to_frame(loc)defisElementPresent(self,element_xpath):"""封裝一個函數,用來判斷頁面某個值是否存在:paramelement_xpath"""try:self.driver.find_element_by_xpath(element_xpath)returnTrueexcept:returnFalse
(2)在common包下新建一個driver.py文件,作用:瀏覽器選擇,默認為谷歌瀏覽器。driver.py文件代碼如下:
#coding=utf-8"""------------------------------------@Time:2020/01/15@Auth:Anker@File:driver.py@Description:瀏覽器選擇,默認為谷歌瀏覽器@IDE:PyCharm@Motto:Believeinyourselfandpersistencecanmakesuccess!------------------------------------"""fromseleniumimportwebdriverbrowser_type="Chrome"defopen_browser():"""瀏覽器選擇(Selenium支持Chrome、Firefox、IE瀏覽器):param:"""globaldriverifbrowser_type=='Firefox':driver=webdriver.Firefox()elifbrowser_type=='Chrome':driver=webdriver.Chrome()elifbrowser_type=='IE':driver=webdriver.Ie()elifbrowser_type=='':driver=webdriver.Chrome()returndriverif__name__=='__main__':driver=open_browser()
(3)在common包下新建一個HTMLTestRunner.py文件,作用:用于生成html報告文件。HTMLTestRunner.py文件代碼如下:
#-*-coding:utf-8-*-"""ATestRunnerforusewiththePythonunittestingframework.ItgeneratesaHTMLreporttoshowtheresultataglance.Thesimplestwaytousethisistoinvokeitsmainmethod.E.g.importunittestimportHTMLTestRunner...defineyourtests...if__name__=='__main__':HTMLTestRunner.main()Formorecustomizationoptions,instantiatesaHTMLTestRunnerobject.HTMLTestRunnerisacounterparttounittest'sTextTestRunner.E.g.#outputtoafilefp=file('my_report.html','wb')runner=HTMLTestRunner.HTMLTestRunner(stream=fp,title='Myunittest',description='ThisdemonstratesthereportoutputbyHTMLTestRunner.')#Useanexternalstylesheet.#SeetheTemplate_mixinclassformorecustomizableoptionsrunner.STYLESHEET_TMPL='<linkrel="stylesheet"href="my_stylesheet.css"rel="externalnofollow"type="text/css">'#runthetestrunner.run(my_test_suite)------------------------------------------------------------------------Copyright(c)2004-2007,WaiYipTungAllrightsreserved.Redistributionanduseinsourceandbinaryforms,withorwithoutmodification,arepermittedprovidedthatthefollowingconditionsaremet:*Redistributionsofsourcecodemustretaintheabovecopyrightnotice,thislistofconditionsandthefollowingdisclaimer.*Redistributionsinbinaryformmustreproducetheabovecopyrightnotice,thislistofconditionsandthefollowingdisclaimerinthedocumentationand/orothermaterialsprovidedwiththedistribution.*NeitherthenameWaiYipTungnorthenamesofitscontributorsmaybeusedtoendorseorpromoteproductsderivedfromthissoftwarewithoutspecificpriorwrittenpermission.THISSOFTWAREISPROVIDEDBYTHECOPYRIGHTHOLDERSANDCONTRIBUTORS"ASIS"ANDANYEXPRESSORIMPLIEDWARRANTIES,INCLUDING,BUTNOTLIMITEDTO,THEIMPLIEDWARRANTIESOFMERCHANTABILITYANDFITNESSFORAPARTICULARPURPOSEAREDISCLAIMED.INNOEVENTSHALLTHECOPYRIGHTOWNERORCONTRIBUTORSBELIABLEFORANYDIRECT,INDIRECT,INCIDENTAL,SPECIAL,EXEMPLARY,ORCONSEQUENTIALDAMAGES(INCLUDING,BUTNOTLIMITEDTO,PROCUREMENTOFSUBSTITUTEGOODSORSERVICES;LOSSOFUSE,DATA,ORPROFITS;ORBUSINESSINTERRUPTION)HOWEVERCAUSEDANDONANYTHEORYOFLIABILITY,WHETHERINCONTRACT,STRICTLIABILITY,ORTORT(INCLUDINGNEGLIGENCEOROTHERWISE)ARISINGINANYWAYOUTOFTHEUSEOFTHISSOFTWARE,EVENIFADVISEDOFTHEPOSSIBILITYOFSUCHDAMAGE."""#URL:http://tungwaiyip.info/software/HTMLTestRunner.html__author__="WaiYipTung"__version__="0.8.3""""ChangeHistoryVersion0.8.4byGoverSky*Addsopportfor3.x*Addpiechartforresultpiechart*AddScreenshotforselenium_casetest*AddRetryonfailedVersion0.8.3*Preventcrashonclassormodule-levelexceptions(DarrenWurf).Version0.8.2*Showoutputinlineinsteadofpopupwindow(ViorelLupu).Versionin0.8.1*ValidatedXHTML(WolfgangBorgert).*Addeddescriptionoftestclassesandtestcases.Versionin0.8.0*DefineTemplate_mixinclassforcustomization.*WorkaroundaIE6bugthatitdoesnottreat<script>blockasCDATA.Versionin0.7.1*BackporttoPython2.3(FrankHorowitz).*Fixmissingscrollbarsindetaillog(Podi)."""#TODO:colorstderr#TODO:simplifyjavascriptusing,orethan1classintheclassattribute?importdatetimeimportsysimportunittestfromxml.saximportsaxutilsPY3K=(sys.version_info[0]>2)ifPY3K:importioasStringIOelse:importStringIOimportcopy#------------------------------------------------------------------------#Theredirectorsbelowareusedtocaptureoutputduringtesting.Output#senttosys.stdoutandsys.stderrareautomaticallycaptured.However#insomecasessys.stdoutisalreadycachedbeforeHTMLTestRunneris#invoked(e.g.callinglogging_demo.basicConfig).Inordertocapturethose#output,usetheredirectorsforthecachedstream.##e.g.#>>>logging_demo.basicConfig(stream=HTMLTestRunner.stdout_redirector)#>>>classOutputRedirector(object):"""Wrappertoredirectstdoutorstderr"""def__init__(self,fp):self.fp=fpdefwrite(self,s):self.fp.write(s)defwritelines(self,lines):self.fp.writelines(lines)defflush(self):self.fp.flush()stdout_redirector=OutputRedirector(sys.stdout)stderr_redirector=OutputRedirector(sys.stderr)#----------------------------------------------------------------------#TemplateclassTemplate_mixin(object):"""DefineaHTMLtemplateforreportcustomerizationandgeneration.OverallstructureofanHTMLreportHTML+------------------------+|<html>||<head>||||STYLESHEET||+----------------+||||||+----------------+||||</head>||||<body>||||HEADING||+----------------+||||||+----------------+||||REPORT||+----------------+||||||+----------------+||||ENDING||+----------------+||||||+----------------+||||</body>||</html>|+------------------------+"""STATUS={0:u'通過',1:u'失敗',2:u'錯誤',}DEFAULT_TITLE='UnitTestReport'DEFAULT_DESCRIPTION=''#------------------------------------------------------------------------#HTMLTemplateHTML_TMPL=r"""<?xmlversion="1.0"encoding="UTF-8"?><!DOCTYPEhtmlPUBLIC"-//W3C//DTDXHTML1.0Strict//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><htmlxmlns="http://www.w3.org/1999/xhtml"><head><title>%(title)s</title><metaname="generator"content="%(generator)s"/><metahttp-equiv="Content-Type"content="text/html;charset=UTF-8"/>%(stylesheet)s</head><body><scriptlanguage="javascript"type="text/javascript">output_list=Array();/*level-0:Summary;1:Failed;2:All*/functionshowCase(level){trs=document.getElementsByTagName("tr");for(vari=0;i<trs.length;i++){tr=trs[i];id=tr.id;if(id.substr(0,2)=='ft'){if(level<1){tr.className='hiddenRow';}else{tr.className='';}}if(id.substr(0,2)=='pt'){if(level>1){tr.className='';}else{tr.className='hiddenRow';}}}}functionshowClassDetail(cid,count){varid_list=Array(count);vartoHide=1;for(vari=0;i<count;i++){tid0='t'+cid.substr(1)+'.'+(i+1);tid='f'+tid0;tr=document.getElementById(tid);if(!tr){tid='p'+tid0;tr=document.getElementById(tid);}id_list[i]=tid;if(tr.className){toHide=0;}}for(vari=0;i<count;i++){tid=id_list[i];if(toHide){document.getElementById(tid).className='hiddenRow';}else{document.getElementById(tid).className='';}}}functionshowTestDetail(p_id){vardetails_p=document.getElementById(p_id)vardisplayState=details_p.style.display//alert(displayState)if(displayState!='block'){displayState='block'details_p.style.display='block'}else{details_p.style.display='none'}}functionhtml_escape(s){s=s.replace(/&/g,'&');s=s.replace(/</g,'<');s=s.replace(/>/g,'>');returns;}functiondrawCircle(pass,fail,error){varcolor=["#6c6","#c60","#c00"];vardata=[pass,fail,error];vartext_arr=["pass","fail","error"];varcanvas=document.getElementById("circle");varctx=canvas.getContext("2d");varstartPoint=0;varwidth=20,height=10;varposX=112*2+20,posY=30;vartextX=posX+width+5,textY=posY+10;for(vari=0;i<data.length;i++){ctx.fillStyle=color[i];ctx.beginPath();ctx.moveTo(112,84);ctx.arc(112,84,84,startPoint,startPoint+Math.PI*2*(data[i]/(data[0]+data[1]+data[2])),false);ctx.fill();startPoint+=Math.PI*2*(data[i]/(data[0]+data[1]+data[2]));ctx.fillStyle=color[i];ctx.fillRect(posX,posY+20*i,width,height);ctx.moveTo(posX,posY+20*i);ctx.font='bold14px';ctx.fillStyle=color[i];varpercent=text_arr[i]+":"+data[i];ctx.fillText(percent,textX,textY+20*i);}}functionshow_img(obj){varobj1=obj.nextElementSiblingobj1.style.display='block'varindex=0;//每張圖片的下標,varlen=obj1.getElementsByTagName('img').length;varimgyuan=obj1.getElementsByClassName('imgyuan')[0]//varstart=setInterval(autoPlay,500);obj1.onmouseover=function(){//當鼠標光標停在圖片上,則停止輪播clearInterval(start);}obj1.onmouseout=function(){//當鼠標光標停在圖片上,則開始輪播start=setInterval(autoPlay,1000);}for(vari=0;i<len;i++){varfont=document.createElement('font')imgyuan.appendChild(font)}varlis=obj1.getElementsByTagName('font');//得到所有圓圈changeImg(0)varfunny=function(i){lis[i].onmouseover=function(){index=ichangeImg(i)}}for(vari=0;i<lis.length;i++){funny(i);}functionautoPlay(){if(index>len-1){index=0;clearInterval(start);//運行一輪后停止}changeImg(index++);}imgyuan.style.width=25*len+"px";//對應圓圈和圖片同步functionchangeImg(index){varlist=obj1.getElementsByTagName('img');varlist1=obj1.getElementsByTagName('font');for(i=0;i<list.length;i++){list[i].style.display='none';list1[i].style.backgroundColor='white';}list[index].style.display='block';list1[index].style.backgroundColor='blue';}}functionhide_img(obj){obj.parentElement.style.display="none";obj.parentElement.getElementsByClassName('imgyuan')[0].innerHTML="";}</script><pclass="piechart"><p><canvasid="circle"width="350"height="168"</canvas></p></p>%(heading)s%(report)s%(ending)s</body></html>"""#variables:(title,generator,stylesheet,heading,report,ending)#------------------------------------------------------------------------#Stylesheet##alternativelyusea<link>forexternalstylesheet,e.g.#<linkrel="stylesheet"href="$url"rel="externalnofollow"type="text/css">STYLESHEET_TMPL="""<styletype="text/css"media="screen">body{font-family:verdana,arial,helvetica,sans-serif;font-size:80%;}table{font-size:100%;}pre{white-space:pre-wrap;word-wrap:break-word;}/*--heading----------------------------------------------------------------------*/h2{font-size:16pt;color:gray;}.heading{margin-top:0ex;margin-bottom:1ex;}.heading.attribute{margin-top:1ex;margin-bottom:0;}.heading.description{margin-top:4ex;margin-bottom:6ex;}/*--cssppopup------------------------------------------------------------------------*/a.popup_link{}a.popup_link:hover{color:red;}.img{height:100%;border-collapse:collapse;border:2pxsolid#777;}.screenshots{z-index:100;position:absolute;height:80%;left:50%;top:50%;transform:translate(-50%,-50%);display:none;}.imgyuan{height:20px;border-radius:12px;background-color:red;padding-left:13px;margin:0auto;position:relative;top:-40px;background-color:rgba(1,150,0,0.3);}.imgyuanfont{border:1pxsolidwhite;width:11px;height:11px;border-radius:50%;margin-right:9px;margin-top:4px;display:block;float:left;background-color:white;}.close_shots{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAJYAAACWCAYAAAA8AXHiAAAACXBIWXMAAAsTAAALEwEAmpwYAAAKT2lDQ1BQaG90b3Nob3AgSUNDIHByb2ZpbGUAAHjanVNnVFPpFj333vRCS4iAlEtvUhUIIFJCi4AUkSYqIQkQSoghodkVUcERRUUEG8igiAOOjoCMFVEsDIoK2AfkIaKOg6OIisr74Xuja9a89+bN/rXXPues852zzwfACAyWSDNRNYAMqUIeEeCDx8TG4eQuQIEKJHAAEAizZCFz/SMBAPh+PDwrIsAHvgABeNMLCADATZvAMByH/w/qQplcAYCEAcB0kThLCIAUAEB6jkKmAEBGAYCdmCZTAKAEAGDLY2LjAFAtAGAnf+bTAICd+Jl7AQBblCEVAaCRACATZYhEAGg7AKzPVopFAFgwABRmS8Q5ANgtADBJV2ZIALC3AMDOEAuyAAgMADBRiIUpAAR7AGDIIyN4AISZABRG8lc88SuuEOcqAAB4mbI8uSQ5RYFbCC1xB1dXLh5ozkkXKxQ2YQJhmkAuwnmZGTKBNA/g88wAAKCRFRHgg/P9eM4Ors7ONo62Dl8t6r8G/yJiYuP+5c+rcEAAAOF0ftH+LC+zGoA7BoBt/qIl7gRoXgugdfeLZrIPQLUAoOnaV/Nw+H48PEWhkLnZ2eXk5NhKxEJbYcpXff5nwl/AV/1s+X48/Pf14L7iJIEyXYFHBPjgwsz0TKUcz5IJhGLc5o9H/LcL//wd0yLESWK5WCoU41EScY5EmozzMqUiiUKSKcUl0v9k4t8s+wM+3zUAsGo+AXuRLahdYwP2SycQWHTA4vcAAPK7b8HUKAgDgGiD4c93/+8//UegJQCAZkmScQAAXkQkLlTKsz/HCAAARKCBKrBBG/TBGCzABhzBBdzBC/xgNoRCJMTCQhBCCMSAHHJgKayCQiiGzbAdKmAv1EAdNMBRaIaTcA4uwlW4Dj1wD/phCJ7BKLyBCQRByAgTYSHaiAFiilgjjggXmYX4IcFIBBKLJCDJiBRRIkuRNUgxUopUIFVIHfI9cgI5h2xGupE7yAAygvyGvEcxlIGyUT3UDLVDuag3GoRGogvQZHQxmo8WoJvQcrQaPYw2oefQq2gP2o8+Q8cwwOgYBzPEbDAuxsNCsTgsCZNjy7EirAyrxhqwVqwDu4n1Y8+xdwQSgUXACTYEd0IgYR5BSFhMWE7YSKggHCQ0EdoJNwkDhFHCJyKTqEu0JroR+cQYYjIxh2hILCPWEo8TLxB7iEPENyQSiUMyJ7mQAkmxpFTSEtJG0m5SI+ksqZs0SBojk8naZGuyBzmULCAryIXkneTD5DPkG+Qh8lsKnWJAcaT4U+IoUspqShnlEOU05QZlmDJBVaOaUt2ooVQRNY9aQq2htlKvUYeoEzR1mjnNgxZJS6WtopXTGmgXaPdpr+h0uhHdlR5Ol9BX0svpR+iX6AP0dwwNhhWDx4hnKBmbGAcYZxl3GK+YTKYZ04sZx1QwNzHrmOeZD5lvVVgqtip8FZHKCpVKlSaVGyovVKmqpqreqgtV81XLVI+pXlN9rkZVM1PjqQnUlqtVqp1Q61MbU2epO6iHqmeob1Q/pH5Z/YkGWcNMw09DpFGgsV/jvMYgC2MZs3gsIWsNq4Z1gTXEJrHN2Xx2KruY/R27iz2qqaE5QzNKM1ezUvOUZj8H45hx+Jx0TgnnKKeX836K3hTvKeIpG6Y0TLkxZVxrqpaXllirSKtRq0frvTau7aedpr1Fu1n7gQ5Bx0onXCdHZ4/OBZ3nU9lT3acKpxZNPTr1ri6qa6UbobtEd79up+6Ynr5egJ5Mb6feeb3n+hx9L/1U/W36p/VHDFgGswwkBtsMzhg8xTVxbzwdL8fb8VFDXcNAQ6VhlWGX4YSRudE8o9VGjUYPjGnGXOMk423GbcajJgYmISZLTepN7ppSTbmmKaY7TDtMx83MzaLN1pk1mz0x1zLnm+eb15vft2BaeFostqi2uGVJsuRaplnutrxuhVo5WaVYVVpds0atna0l1rutu6cRp7lOk06rntZnw7Dxtsm2qbcZsOXYBtuutm22fWFnYhdnt8Wuw+6TvZN9un2N/T0HDYfZDqsdWh2+c7RyFDpWOt6azpzuP33F9JbpL2dYzxDP2DPjthPLKcRpnVOb00dnF2e5c4PziIuJS4LLLpc+Lpsbxt3IveRKdPVxXeF60vWdm7Obwu2o26/uNu5p7ofcn8w0nymeWTNz0MPIQ+BR5dE/C5+VMGvfrH5PQ0+BZ7XnIy9jL5FXrdewt6V3qvdh7xc+9j5yn+M+4zw33jLeWV/MN8C3yLfLT8Nvnl+F30N/I/9k/3r/0QCngCUBZwOJgUGBWwL7+Hp8Ib+OPzrbZfay2e1BjKC5QRVBj4KtguXBrSFoyOyQrSH355jOkc5pDoVQfujW0Adh6mGLw34MJ4WHhVeGP45wiFga0TGXNXfR3ENz30T6RJZE3ptnMU85ry1KNSo+qi5qPNo3ujS6P8YuZlnM1VidWElsSxw5LiquNm5svt/87fOH4p3iC+N7F5gvyF1weaHOwvSFpxapLhIsOpZATIhOOJTwQRAqqBaMJfITdyWOCnnCHcJnIi/RNtGI2ENcKh6O8kgqTXqS7JG8NXkkxTOlLOW5hCepkLxMDUzdmzqeFpp2IG0yPTq9MYOSkZBxQqohTZO2Z+pn5mZ2y6xlhbL+xW6Lty8elQfJa7OQrAVZLQq2QqboVFoo1yoHsmdlV2a/zYnKOZarnivN7cyzytuQN5zvn//tEsIS4ZK2pYZLVy0dWOa9rGo5sjxxedsK4xUFK4ZWBqw8uIq2Km3VT6vtV5eufr0mek1rgV7ByoLBtQFr6wtVCuWFfevc1+1dT1gvWd+1YfqGnRs+FYmKrhTbF5cVf9go3HjlG4dvyr+Z3JS0qavEuWTPZtJm6ebeLZ5bDpaql+aXDm4N2dq0Dd9WtO319kXbL5fNKNu7g7ZDuaO/PLi8ZafJzs07P1SkVPRU+lQ27tLdtWHX+G7R7ht7vPY07NXbW7z3/T7JvttVAVVN1WbVZftJ+7P3P66Jqun4lvttXa1ObXHtxwPSA/0HIw6217nU1R3SPVRSj9Yr60cOxx++/p3vdy0NNg1VjZzG4iNwRHnk6fcJ3/ceDTradox7rOEH0x92HWcdL2pCmvKaRptTmvtbYlu6T8w+0dbq3nr8R9sfD5w0PFl5SvNUyWna6YLTk2fyz4ydlZ19fi753GDborZ752PO32oPb++6EHTh0kX/i+c7vDvOXPK4dPKy2+UTV7hXmq86X23qdOo8/pPTT8e7nLuarrlca7nuer21e2b36RueN87d9L158Rb/1tWeOT3dvfN6b/fF9/XfFt1+cif9zsu72Xcn7q28T7xf9EDtQdlD3YfVP1v+3Njv3H9qwHeg89HcR/cGhYPP/pH1jw9DBY+Zj8uGDYbrnjg+OTniP3L96fynQ89kzyaeF/6i/suuFxYvfvjV69fO0ZjRoZfyl5O/bXyl/erA6xmv28bCxh7+yXgzMV70VvvtwXfcdx3vo98PT+R8IH8o/2j5sfVT0Kf7kxmTk/8EA5jz/GMzLdsAAD+3aVRYdFhNTDpjb20uYWRvYmUueG1wAAAAAAA8P3hwYWNrZXQgYmVnaW49Iu+7vyIgaWQ9Ilc1TTBNcENlaGlIenJlU3pOVGN6a2M5ZCI/Pgo8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJBZG9iZSBYTVAgQ29yZSA1LjYtYzA2NyA3OS4xNTc3NDcsIDIwMTUvMDMvMzAtMjM6NDA6NDIgICAgICAgICI+CiAgIDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+CiAgICAgIDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiCiAgICAgICAgICAgIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIgogICAgICAgICAgICB4bWxuczpzdEV2dD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlRXZlbnQjIgogICAgICAgICAgICB4bWxuczpzdFJlZj0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlUmVmIyIKICAgICAgICAgICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICAgICAgICAgICB4bWxuczpwaG90b3Nob3A9Imh0dHA6Ly9ucy5hZG9iZS5jb20vcGhvdG9zaG9wLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIKICAgICAgICAgICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOmV4aWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vZXhpZi8xLjAvIj4KICAgICAgICAgPHhtcE1NOkRvY3VtZW50SUQ+YWRvYmU6ZG9jaWQ6cGhvdG9zaG9wOjk4NDVkYzlhLTM2NTEtMTFlOC1hMDRjLWMzZmRjNzFmNjFkZDwveG1wTU06RG9jdW1lbnRJRD4KICAgICAgICAgPHhtcE1NOkluc3RhbmNlSUQ+eG1wLmlpZDo3YzQ4OTMyZS0wM2FjLTIxNDctYTJiZi1iNmViOWU4ZDY2Y2Q8L3htcE1NOkluc3RhbmNlSUQ+CiAgICAgICAgIDx4bXBNTTpPcmlnaW5hbERvY3VtZW50SUQ+MEIzOTNDRjk1RDQ0RDlGMDNFQjEzQkZEQ0UxRDA5MjM8L3htcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD4KICAgICAgICAgPHhtcE1NOkhpc3Rvcnk+CiAgICAgICAgICAgIDxyZGY6U2VxPgogICAgICAgICAgICAgICA8cmRmOmxpIHJkZjpwYXJzZVR5cGU9IlJlc291cmNlIj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OmFjdGlvbj5zYXZlZDwvc3RFdnQ6YWN0aW9uPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6aW5zdGFuY2VJRD54bXAuaWlkOmQ0ZjMzNDFjLTRkYjctZjc0YS1iZTAxLWYxMGEwMzNhNjg4ZDwvc3RFdnQ6aW5zdGFuY2VJRD4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OndoZW4+MjAxOC0wNC0wMlQxNjo0MToxMCswODowMDwvc3RFdnQ6d2hlbj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OnNvZnR3YXJlQWdlbnQ+QWRvYmUgUGhvdG9zaG9wIEVsZW1lbnRzIDE0LjAgKFdpbmRvd3MpPC9zdEV2dDpzb2Z0d2FyZUFnZW50PgogICAgICAgICAgICAgICAgICA8c3RFdnQ6Y2hhbmdlZD4vPC9zdEV2dDpjaGFuZ2VkPgogICAgICAgICAgICAgICA8L3JkZjpsaT4KICAgICAgICAgICAgICAgPHJkZjpsaSByZGY6cGFyc2VUeXBlPSJSZXNvdXJjZSI+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDphY3Rpb24+Y29udmVydGVkPC9zdEV2dDphY3Rpb24+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDpwYXJhbWV0ZXJzPmZyb20gaW1hZ2UvanBlZyB0byBpbWFnZS9wbmc8L3N0RXZ0OnBhcmFtZXRlcnM+CiAgICAgICAgICAgICAgIDwvcmRmOmxpPgogICAgICAgICAgICAgICA8cmRmOmxpIHJkZjpwYXJzZVR5cGU9IlJlc291cmNlIj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OmFjdGlvbj5kZXJpdmVkPC9zdEV2dDphY3Rpb24+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDpwYXJhbWV0ZXJzPmNvbnZlcnRlZCBmcm9tIGltYWdlL2pwZWcgdG8gaW1hZ2UvcG5nPC9zdEV2dDpwYXJhbWV0ZXJzPgogICAgICAgICAgICAgICA8L3JkZjpsaT4KICAgICAgICAgICAgICAgPHJkZjpsaSByZGY6cGFyc2VUeXBlPSJSZXNvdXJjZSI+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDphY3Rpb24+c2F2ZWQ8L3N0RXZ0OmFjdGlvbj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0Omluc3RhbmNlSUQ+eG1wLmlpZDo3YzQ4OTMyZS0wM2FjLTIxNDctYTJiZi1iNmViOWU4ZDY2Y2Q8L3N0RXZ0Omluc3RhbmNlSUQ+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDp3aGVuPjIwMTgtMDQtMDJUMTY6NDE6MTArMDg6MDA8L3N0RXZ0OndoZW4+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDpzb2Z0d2FyZUFnZW50PkFkb2JlIFBob3Rvc2hvcCBFbGVtZW50cyAxNC4wIChXaW5kb3dzKTwvc3RFdnQ6c29mdHdhcmVBZ2VudD4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OmNoYW5nZWQ+Lzwvc3RFdnQ6Y2hhbmdlZD4KICAgICAgICAgICAgICAgPC9yZGY6bGk+CiAgICAgICAgICAgIDwvcmRmOlNlcT4KICAgICAgICAgPC94bXBNTTpIaXN0b3J5PgogICAgICAgICA8eG1wTU06RGVyaXZlZEZyb20gcmRmOnBhcnNlVHlwZT0iUmVzb3VyY2UiPgogICAgICAgICAgICA8c3RSZWY6aW5zdGFuY2VJRD54bXAuaWlkOmQ0ZjMzNDFjLTRkYjctZjc0YS1iZTAxLWYxMGEwMzNhNjg4ZDwvc3RSZWY6aW5zdGFuY2VJRD4KICAgICAgICAgICAgPHN0UmVmOmRvY3VtZW50SUQ+MEIzOTNDRjk1RDQ0RDlGMDNFQjEzQkZEQ0UxRDA5MjM8L3N0UmVmOmRvY3VtZW50SUQ+CiAgICAgICAgICAgIDxzdFJlZjpvcmlnaW5hbERvY3VtZW50SUQ+MEIzOTNDRjk1RDQ0RDlGMDNFQjEzQkZEQ0UxRDA5MjM8L3N0UmVmOm9yaWdpbmFsRG9jdW1lbnRJRD4KICAgICAgICAgPC94bXBNTTpEZXJpdmVkRnJvbT4KICAgICAgICAgPGRjOmZvcm1hdD5pbWFnZS9wbmc8L2RjOmZvcm1hdD4KICAgICAgICAgPHBob3Rvc2hvcDpDb2xvck1vZGU+MzwvcGhvdG9zaG9wOkNvbG9yTW9kZT4KICAgICAgICAgPHBob3Rvc2hvcDpJQ0NQcm9maWxlPnNSR0IgSUVDNjE5NjYtMi4xPC9waG90b3Nob3A6SUNDUHJvZmlsZT4KICAgICAgICAgPHhtcDpDcmVhdGVEYXRlPjIwMTgtMDQtMDJUMTY6MjM6NTUrMDg6MDA8L3htcDpDcmVhdGVEYXRlPgogICAgICAgICA8eG1wOk1vZGlmeURhdGU+MjAxOC0wNC0wMlQxNjo0MToxMCswODowMDwveG1wOk1vZGlmeURhdGU+CiAgICAgICAgIDx4bXA6TWV0YWRhdGFEYXRlPjIwMTgtMDQtMDJUMTY6NDE6MTArMDg6MDA8L3htcDpNZXRhZGF0YURhdGU+CiAgICAgICAgIDx4bXA6Q3JlYXRvclRvb2w+QWRvYmUgUGhvdG9zaG9wIEVsZW1lbnRzIDE0LjAgKFdpbmRvd3MpPC94bXA6Q3JlYXRvclRvb2w+CiAgICAgICAgIDx0aWZmOkltYWdlV2lkdGg+MjU0PC90aWZmOkltYWdlV2lkdGg+CiAgICAgICAgIDx0aWZmOkltYWdlTGVuZ3RoPjI1NDwvdGlmZjpJbWFnZUxlbmd0aD4KICAgICAgICAgPHRpZmY6Qml0c1BlclNhbXBsZT4KICAgICAgICAgICAgPHJkZjpTZXE+CiAgICAgICAgICAgICAgIDxyZGY6bGk+ODwvcmRmOmxpPgogICAgICAgICAgICAgICA8cmRmOmxpPjg8L3JkZjpsaT4KICAgICAgICAgICAgICAgPHJkZjpsaT44PC9yZGY6bGk+CiAgICAgICAgICAgIDwvcmRmOlNlcT4KICAgICAgICAgPC90aWZmOkJpdHNQZXJTYW1wbGU+CiAgICAgICAgIDx0aWZmOlBob3RvbWV0cmljSW50ZXJwcmV0YXRpb24+MjwvdGlmZjpQaG90b21ldHJpY0ludGVycHJldGF0aW9uPgogICAgICAgICA8dGlmZjpPcmllbnRhdGlvbj4xPC90aWZmOk9yaWVudGF0aW9uPgogICAgICAgICA8dGlmZjpTYW1wbGVzUGVyUGl4ZWw+MzwvdGlmZjpTYW1wbGVzUGVyUGl4ZWw+CiAgICAgICAgIDx0aWZmOlhSZXNvbHV0aW9uPjcyMDAwMC8xMDAwMDwvdGlmZjpYUmVzb2x1dGlvbj4KICAgICAgICAgPHRpZmY6WVJlc29sdXRpb24+NzIwMDAwLzEwMDAwPC90aWZmOllSZXNvbHV0aW9uPgogICAgICAgICA8dGlmZjpSZXNvbHV0aW9uVW5pdD4yPC90aWZmOlJlc29sdXRpb25Vbml0PgogICAgICAgICA8ZXhpZjpFeGlmVmVyc2lvbj4wMjIxPC9leGlmOkV4aWZWZXJzaW9uPgogICAgICAgICA8ZXhpZjpDb2xvclNwYWNlPjE8L2V4aWY6Q29sb3JTcGFjZT4KICAgICAgICAgPGV4aWY6UGl4ZWxYRGltZW5zaW9uPjE1MDwvZXhpZjpQaXhlbFhEaW1lbnNpb24+CiAgICAgICAgIDxleGlmOlBpeGVsWURpbWVuc2lvbj4xNTA8L2V4aWY6UGl4ZWxZRGltZW5zaW9uPgogICAgICA8L3JkZjpEZXNjcmlwdGlvbj4KICAgPC9yZGY6UkRGPgo8L3g6eG1wbWV0YT4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAg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);background-size:22px22px;-moz-background-size:22px22px;background-repeat:no-repeat;position:absolute;top:5px;right:5px;height:22px;z-index:99;width:22px;}.popup_window{display:none;position:relative;left:0px;top:0px;padding:10px;background-color:#E6E6D6;font-family:"LucidaConsole","CourierNew",Courier,monospace;text-align:left;font-size:8pt;}}/*--report------------------------------------------------------------------------*/#show_detail_line{margin-top:3ex;margin-bottom:1ex;}#result_table{margin:1em0;width:100%;overflow:hidden;background:#FFF;color:#024457;border-radius:10px;border:1pxsolid#167F92;}#result_tableth{border:1pxsolid#FFFFFF;background-color:#167F92;color:#FFF;padding:0.5em;&:first-child{display:table-cell;text-align:center;}&:nth-child(2){display:table-cell;span{display:none;}&:after{content:attr(data-th);}}@media(min-width:480px){&:nth-child(2){span{display:block;}&:after{display:none;}}}}#result_tabletd{word-wrap:break-word;max-width:7em;padding:0.3em;&:first-child{display:table-cell;text-align:center;}@media(min-width:400px){border:1pxsolid#D9E4E6;}}#result_tableth,td{margin:.5em1em;@media(min-width:400px){display:table-cell;padding:1em;}}#total_row{font-weight:bold;}.passClass{background-color:#6c6;!important;}.failClass{background-color:#c60;!important;}.errorClass{background-color:#c00;!important;}.passCase{color:#6c6;}.failCase{color:#c60;font-weight:bold;}.errorCase{color:#c00;font-weight:bold;}tr[id^=pt]td{background-color:rgba(73,204,144,.3)!important;}tr[id^=ft]td{background-color:rgba(252,161,48,.3)!important;}tr[id^=et]td{background-color:rgba(249,62,62,.3)!important;}.hiddenRow{display:none;}.testcase{margin-left:2em;}/*--ending----------------------------------------------------------------------*/#ending{}.piechart{position:absolute;;top:20px;left:300px;width:200px;float:left;display:inline;}</style>"""#------------------------------------------------------------------------#Heading#HEADING_TMPL="""<pclass='heading'><h2>%(title)s</h2>%(parameters)s<pclass='description'>%(description)s</p></p>"""#variables:(title,parameters,description)HEADING_ATTRIBUTE_TMPL="""<pclass='attribute'><strong>%(name)s:</strong>%(value)s</p>"""#variables:(name,value)#------------------------------------------------------------------------#Report#REPORT_TMPL="""<pid='show_detail_line'>顯示<ahref='javascript:showCase(0)'>概要</a><ahref='javascript:showCase(1)'>失敗</a><ahref='javascript:showCase(2)'>所有</a></p><tableid='result_table'><colgroup><colalign='left'/><colalign='right'/><colalign='right'/><colalign='right'/><colalign='right'/><colalign='right'/><colalign='right'/></colgroup><trid='header_row'><th>測試組/測試用例</th><th>總數</th><th>通過</th><th>失敗</th><th>錯誤</th><th>視圖</th><th>錯誤截圖</th></tr>%(test_list)s<trid='total_row'><th>統計</th><th>%(count)s</th><th>%(Pass)s</th><th>%(fail)s</th><th>%(error)s</th><th> </th><th> </th></tr></table><script>showCase(1);drawCircle(%(Pass)s,%(fail)s,%(error)s);</script>"""#variables:(test_list,count,Pass,fail,error)REPORT_CLASS_TMPL=r"""<trclass='%(style)s'><td>%(desc)s</td><td>%(count)s</td><td>%(Pass)s</td><td>%(fail)s</td><td>%(error)s</td><td><ahref="javascript:showClassDetail('%(cid)s',%(count)s)"rel="externalnofollow">詳情</a></td><td> </td></tr>"""#variables:(style,desc,count,Pass,fail,error,cid)REPORT_TEST_WITH_OUTPUT_TMPL=r"""<trid='%(tid)s'class='%(Class)s'><td><pclass='testcase'>%(desc)s</p></td><tdcolspan='5'align='center'><!--cssppopupstart--><spanclass='status%(style)s'><aclass="popup_link"onfocus='this.blur();'href="javascript:showTestDetail('p_%(tid)s')"rel="externalnofollow">%(status)s</a></span><pid='p_%(tid)s'class="popup_window"><pstyle='text-align:right;color:red;cursor:pointer'><aonfocus='this.blur();'onclick="document.getElementById('p_%(tid)s').style.display='none'">[x]</a></p><pre>%(script)s</pre></p><!--cssppopupend--></td><td>%(img)s</td></tr>"""#variables:(tid,Class,style,desc,status,img)REPORT_TEST_NO_OUTPUT_TMPL=r"""<trid='%(tid)s'class='%(Class)s'><td><pclass='testcase'>%(desc)s</p></td><tdcolspan='5'align='center'><spanclass='status%(style)s'>%(status)s</span></td><td>%(img)s</td></tr>"""#variables:(tid,Class,style,desc,status,img)REPORT_TEST_OUTPUT_TMPL=r"""%(id)s:%(output)s"""#variables:(id,output)IMG_TMPL=r"""<ahref="#"rel="externalnofollow"rel="externalnofollow"onclick="show_img(this)">顯示截圖</a><palign="center"class="screenshots"><aclass="close_shots"href="#"rel="externalnofollow"rel="externalnofollow"onclick="hide_img(this)"></a>%(imgs)s<pclass="imgyuan"></p></p>"""#------------------------------------------------------------------------#ENDING#ENDING_TMPL="""<pid='ending'> </p>"""#--------------------TheendoftheTemplateclass-------------------def__getattribute__(self,item):value=object.__getattribute__(self,item)ifPY3K:returnvalueelse:ifisinstance(value,str):returnvalue.decode("utf-8")else:returnvalueTestResult=unittest.TestResultclass_TestResult(TestResult):#note:_TestResultisapurerepresentationofresults.#Itlackstheoutputandreportingabilitycomparestounittest._TextTestResult.def__init__(self,verbosity=1,retry=0,save_last_try=True):TestResult.__init__(self)self.stdout0=Noneself.stderr0=Noneself.success_count=0self.failure_count=0self.error_count=0self.verbosity=verbosity#resultisalistofresultin4tuple#(#resultcode(0:success;1:fail;2:error),#TestCaseobject,#Testoutput(bytestring),#stacktrace,#)self.result=[]self.retry=retryself.trys=0self.status=0self.save_last_try=save_last_tryself.outputBuffer=StringIO.StringIO()defstartTest(self,test):test.imgs=[]#test.imgs=getattr(test,"imgs",[])TestResult.startTest(self,test)self.outputBuffer.seek(0)self.outputBuffer.truncate()stdout_redirector.fp=self.outputBufferstderr_redirector.fp=self.outputBufferself.stdout0=sys.stdoutself.stderr0=sys.stderrsys.stdout=stdout_redirectorsys.stderr=stderr_redirectordefcomplete_output(self):"""Disconnectoutputredirectionandreturnbuffer.Safetocallmultipletimes."""ifself.stdout0:sys.stdout=self.stdout0sys.stderr=self.stderr0self.stdout0=Noneself.stderr0=Nonereturnself.outputBuffer.getvalue()defstopTest(self,test):#UsuallyoneofaddSuccess,addErrororaddFailurewouldhavebeencalled.#Buttherearesomepathinunittestthatwouldbypassthis.#WemustdisconnectstdoutinstopTest(),whichisguaranteedtobecalled.ifself.retry:ifself.status==1:self.trys+=1ifself.trys<=self.retry:ifself.save_last_try:t=self.result.pop(-1)ift[0]==1:self.failure_count-=1else:self.error_count-=1test=copy.copy(test)sys.stderr.write("Retesting...")sys.stderr.write(str(test))sys.stderr.write('..%d\n'%self.trys)doc=test._testMethodDocor''ifdoc.find('_retry')!=-1:doc=doc[:doc.find('_retry')]desc="%s_retry:%d"%(doc,self.trys)ifnotPY3K:ifisinstance(desc,str):desc=desc.decode("utf-8")test._testMethodDoc=desctest(self)else:self.status=0self.trys=0self.complete_output()defaddSuccess(self,test):self.success_count+=1self.status=0TestResult.addSuccess(self,test)output=self.complete_output()self.result.append((0,test,output,''))ifself.verbosity>1:sys.stderr.write('ok')sys.stderr.write(str(test))sys.stderr.write('\n')else:sys.stderr.write('.')defaddError(self,test,err):self.error_count+=1self.status=1TestResult.addError(self,test,err)_,_exc_str=self.errors[-1]output=self.complete_output()self.result.append((2,test,output,_exc_str))ifnotgetattr(test,"driver",""):passelse:try:driver=getattr(test,"driver")test.imgs.append(driver.get_screenshot_as_base64())exceptException:passifself.verbosity>1:sys.stderr.write('E')sys.stderr.write(str(test))sys.stderr.write('\n')else:sys.stderr.write('E')defaddFailure(self,test,err):self.failure_count+=1self.status=1TestResult.addFailure(self,test,err)_,_exc_str=self.failures[-1]output=self.complete_output()self.result.append((1,test,output,_exc_str))ifnotgetattr(test,"driver",""):passelse:try:driver=getattr(test,"driver")test.imgs.append(driver.get_screenshot_as_base64())exceptExceptionase:passifself.verbosity>1:sys.stderr.write('F')sys.stderr.write(str(test))sys.stderr.write('\n')else:sys.stderr.write('F')classHTMLTestRunner(Template_mixin):def__init__(self,stream=sys.stdout,verbosity=2,title=None,description=None,retry=0,save_last_try=False):self.stream=streamself.retry=retryself.save_last_try=save_last_tryself.verbosity=verbosityiftitleisNone:self.title=self.DEFAULT_TITLEelse:self.title=titleifdescriptionisNone:self.description=self.DEFAULT_DESCRIPTIONelse:self.description=descriptionself.startTime=datetime.datetime.now()defrun(self,test):"Runthegiventestcaseortestsuite."result=_TestResult(self.verbosity,self.retry,self.save_last_try)test(result)self.stopTime=datetime.datetime.now()self.generateReport(test,result)ifPY3K:#forpython3#print('\nTimeElapsed:%s'%(self.stopTime-self.startTime),file=sys.stderr)output='\nTimeElapsed:%s'%(self.stopTime-self.startTime)sys.stderr.write(output)else:print>>sys.stderr,'\nTimeElapsed:%s'%(self.stopTime-self.startTime)returnresultdefsortResult(self,result_list):#unittestdoesnotseemstoruninanyparticularorder.#Hereatleastwewanttogroupthemtogetherbyclass.rmap={}classes=[]forn,t,o,einresult_list:cls=t.__class__ifnotclsinrmap:rmap[cls]=[]classes.append(cls)rmap[cls].append((n,t,o,e))r=[(cls,rmap[cls])forclsinclasses]returnrdefgetReportAttributes(self,result):"""Returnreportattributesasalistof(name,value).Overridethistoaddcustomattributes."""startTime=str(self.startTime)[:19]duration=str(self.stopTime-self.startTime)status=[]ifresult.success_count:status.append(u'<spanclass="tjpassCase">Pass</span>%s'%result.success_count)ifresult.failure_count:status.append(u'<spanclass="tjfailCase">Failure</span>%s'%result.failure_count)ifresult.error_count:status.append(u'<spanclass="tjerrorCase">Error</span>%s'%result.error_count)ifstatus:status=''.join(status)else:status='none'return[(u'開始時間',startTime),(u'耗時',duration),(u'狀態',status),]defgenerateReport(self,test,result):report_attrs=self.getReportAttributes(result)generator='HTMLTestRunner%s'%__version__stylesheet=self._generate_stylesheet()heading=self._generate_heading(report_attrs)report=self._generate_report(result)ending=self._generate_ending()output=self.HTML_TMPL%dict(title=saxutils.escape(self.title),generator=generator,stylesheet=stylesheet,heading=heading,report=report,ending=ending,)ifPY3K:self.stream.write(output.encode())else:self.stream.write(output.encode('utf8'))def_generate_stylesheet(self):returnself.STYLESHEET_TMPLdef_generate_heading(self,report_attrs):a_lines=[]forname,valueinreport_attrs:line=self.HEADING_ATTRIBUTE_TMPL%dict(name=name,value=value,)a_lines.append(line)heading=self.HEADING_TMPL%dict(title=saxutils.escape(self.title),parameters=''.join(a_lines),description=saxutils.escape(self.description),)returnheadingdef_generate_report(self,result):rows=[]sortedResult=self.sortResult(result.result)forcid,(cls,cls_results)inenumerate(sortedResult):#subtotalforaclassnp=nf=ne=0forn,t,o,eincls_results:ifn==0:np+=1elifn==1:nf+=1else:ne+=1#formatclassdescriptionifcls.__module__=="__main__":name=cls.__name__else:name="%s.%s"%(cls.__module__,cls.__name__)doc=cls.__doc__andcls.__doc__.split("\n")[0]or""desc=docand'%s:%s'%(name,doc)ornameifnotPY3K:ifisinstance(desc,str):desc=desc.decode("utf-8")row=self.REPORT_CLASS_TMPL%dict(style=ne>0and'errorClass'ornf>0and'failClass'or'passClass',desc=desc,count=np+nf+ne,Pass=np,fail=nf,error=ne,cid='c%s'%(cid+1),)rows.append(row)fortid,(n,t,o,e)inenumerate(cls_results):self._generate_report_test(rows,cid,tid,n,t,o,e)report=self.REPORT_TMPL%dict(test_list=u''.join(rows),count=str(result.success_count+result.failure_count+result.error_count),Pass=str(result.success_count),fail=str(result.failure_count),error=str(result.error_count),)returnreportdef_generate_report_test(self,rows,cid,tid,n,t,o,e):#e.g.'pt1.1','ft1.1',etchas_output=bool(oore)tid=(n==0and'p'or'f')+'t%s.%s'%(cid+1,tid+1)name=t.id().split('.')[-1]ifself.verbosity>1:doc=t._testMethodDocor''else:doc=""desc=docand('%s:%s'%(name,doc))ornameifnotPY3K:ifisinstance(desc,str):desc=desc.decode("utf-8")tmpl=has_outputandself.REPORT_TEST_WITH_OUTPUT_TMPLorself.REPORT_TEST_NO_OUTPUT_TMPL#oandeshouldbebytestringbecausetheyarecollectedfromstdoutandstderr?ifisinstance(o,str):#uo=unicode(o.encode('string_escape'))ifPY3K:uo=oelse:uo=o.decode('utf-8','ignore')else:uo=oifisinstance(e,str):#ue=unicode(e.encode('string_escape'))ifPY3K:ue=eelife.find("Error")!=-1ore.find("Exception")!=-1:es=e.decode('utf-8','ignore').split('\n')es[-2]=es[-2].decode('unicode_escape')ue=u"\n".join(es)else:ue=e.decode('utf-8','ignore')else:ue=escript=self.REPORT_TEST_OUTPUT_TMPL%dict(id=tid,output=saxutils.escape(uo+ue),)ifgetattr(t,'imgs',[]):#判斷截圖列表,如果有則追加tmp=u""fori,imginenumerate(t.imgs):ifi==0:tmp+="""<imgsrc="data:image/jpg;base64,%s"class="img"/>\n"""%imgelse:tmp+="""<imgsrc="data:image/jpg;base64,%s"class="img"/>\n"""%imgimgs=self.IMG_TMPL%dict(imgs=tmp)else:imgs=u"""無截圖"""row=tmpl%dict(tid=tid,Class=(n==0and'hiddenRow'or'none'),style=n==2and'errorCase'or(n==1and'failCase'or'passCase'),desc=desc,script=script,status=self.STATUS[n],img=imgs,)rows.append(row)ifnothas_output:returndef_generate_ending(self):returnself.ENDING_TMPL###############################################################################Facilitiesforrunningtestsfromthecommandline###############################################################################Note:Reuseunittest.TestProgramtolaunchtest.Inthefuturewemay#buildourownlaunchertosupportmorespecificcommandline#parametersliketesttitle,CSS,etc.classTestProgram(unittest.TestProgram):"""Avariationoftheunittest.TestProgram.Pleaserefertothebaseclassforcommandlineparameters."""defrunTests(self):#PickHTMLTestRunnerasthedefaulttestrunner.#baseclass'stestRunnerparameterisnotusefulbecauseitmeans#wehavetoinstantiateHTMLTestRunnerbeforeweknowself.verbosity.ifself.testRunnerisNone:self.testRunner=HTMLTestRunner(verbosity=self.verbosity)unittest.TestProgram.runTests(self)main=TestProgram###############################################################################Executingthismodulefromthecommandline##############################################################################if__name__=="__main__":main(module=None)
(4)在common包下新建一個login.py文件,作用:登錄操作。login.py文件代碼如下:
#coding=utf-8"""------------------------------------@Time:2020/01/15@Auth:Anker@File:login.py@purpose:登錄操作@IDE:PyCharm@Motto:Believeinyourselfandpersistencecanmakesuccess!------------------------------------"""fromselenium.webdriver.common.byimportByfromcommon.baseimportBasePageclassLoginPage(BasePage):#通過id的方式去定位用戶名username_loc=(By.ID,"login_username")#通過id的方式去定位用戶密碼password_loc=(By.ID,"login_password")#通過xpath的方式去定位登錄按鈕login_button_loc=(By.XPATH,"//*[text()='登錄']/..")definput_username(self,username):#輸入用戶名self.find_element(*self.username_loc).send_keys(username)definput_password(self,password):#輸入密碼self.find_element(*self.password_loc).send_keys(password)defclick_login_button(self):#點擊登錄按鈕self.find_element(*self.login_button_loc).click()deflogin(self,username="18288888888",password="123456"):self.open_url()self.input_username(username)self.input_password(password)self.click_login_button()returnself.driver
(5)在common包下新建一個unit.py文件,作用:封裝瀏覽器的啟動和關閉的操作。unit.py文件代碼如下:
#coding=utf-8"""------------------------------------@Time:2020/01/15@Auth:Anker@File:unit.py@Description:封裝瀏覽器的啟動和關閉的操作@IDE:PyCharm@Motto:Believeinyourselfandpersistencecanmakesuccess!------------------------------------"""importunittestimportwarnings#導入警告包,避免日志打印中出現報紅的無關緊要的警告fromselenium.webdriver.common.byimportByfromcommon.driverimportopen_browserclassUnit(unittest.TestCase):knowledge_graph_menu=(By.XPATH,'//*/span[text()="知識圖譜"]')#點擊知識圖譜菜單system_management_menu=(By.XPATH,'//*/span[text()="系統管理"]')#點擊系統管理菜單material_definition_menu=(By.XPATH,'//*[text()="物料定義"]')#點擊物料定義菜單material_name_text=(By.ID,"material_name")#輸入物料名稱material_code_text=(By.ID,"material_code")#輸入物料編碼material_unit_text=(By.ID,"material_unit")#輸入物料單位BOM_material_name_id=(By.ID,"material_sourceId")#BOM關聯的物料idBOM_material_name_xpath=(By.XPATH,"//*[@id='material_sourceId']")#BOM關聯的物料xpathBOM_definition_menu=(By.XPATH,'//*[text()="BOM定義"]')#點擊BOM定義菜單procedure_definition_menu=(By.XPATH,'//*[text()="工序定義"]')#點擊工序定義菜單procedure_name_text=(By.ID,"define_name")#輸入工序名稱procedure_device_type_id=(By.ID,"define_typeId")#工序關聯的設備類型idprocedure_device_type_xpath=(By.XPATH,"//*[@id='define_typeId']")#工序關聯的設備類型xpathworkshop_definition_menu=(By.XPATH,'//*[text()="車間定義"]')#點擊車間定義菜單workshop_code_text=(By.ID,"define_code")#輸入車間編碼workshop_name_text=(By.ID,"define_name")#輸入車間名稱workshop_ip_text=(By.ID,"define_ip")#輸入車間IPworkshop_management_text=(By.ID,"define_management")#輸入車間負責人workshop_name_id=(By.ID,"define_workshopId")#關聯的車間idworkshop_name_xpath=(By.XPATH,"//*[@id='define_workshopId']")#關聯的車間xpathipc_definition_menu=(By.XPATH,'//*[text()="終端定義"]')#點擊終端定義菜單ipc_name_text=(By.ID,"define_name")#輸入終端名稱ipc_address_text=(By.ID,"define_address")#輸入終端地址ipc_ip_text=(By.ID,"define_ipcIp")#輸入終端IPipc_remarks_text=(By.ID,"define_remark")#輸入終端備注說明ipc_name_id=(By.ID,"define_ipcList")#關聯的工控機idipc_name_xpath=(By.XPATH,"//*[@id='define_ipcList']")#關聯的工控機xpathfactory_modeling_menu=(By.XPATH,'//*[text()="工廠建模"]')#點擊工廠建模菜單factory_id=(By.ID,"define_factoryId")#關聯的工廠idfactory_xpath=(By.XPATH,"//*[@id='define_factoryId']")#關聯的工廠xpathfactory_name_text=(By.ID,"define_name")#輸入工廠名稱factory_address_text=(By.ID,"define_address")#輸入工廠地址department_management_menu=(By.XPATH,'//*[text()="部門管理"]')#點擊部門管理菜單department_id=(By.ID,"define_deptId")#關聯的部門iddepartment_xpath=(By.XPATH,"//*[@id='define_deptId']")#關聯的部門xpathdepartment_name_text=(By.ID,"define_name")#輸入部門名稱add_button=(By.XPATH,'//*[text()="新增"]/..')#點擊新增按鈕enter_xpath=(By.XPATH,"//*[@class='ant-select-search__field']")#按回車鍵confirm_button=(By.XPATH,"//*[text()='確定']/..")#點擊確定按鈕#新增設備時選擇是否采集yes_no_xpath=(By.XPATH,'//*[@id="define_needCollect"]/label[1]/span[text()="是"]')#新增工序時是否使用模具tools_yes_no_xpath=(By.XPATH,'//*[@id="define_moudle"]/label[2]/span[text()="否"]')#物料選擇自制或外購self_control_xpath=(By.XPATH,'//*/span[text()="自制"]')#選擇是否主工藝路線process_route_yes_no_xpath=(By.XPATH,'//*[@id="define_techType"]/label[1]/span[text()="是"]')device_definition_menu=(By.XPATH,'//*[text()="設備定義"]')#點擊設備定義菜單device_type_text=(By.ID,"define_name")#輸入設備類型device_list_menu=(By.XPATH,'//*[text()="設備列表"]')#點擊設備列表菜單device_code_text=(By.ID,"define_code")#輸入設備編碼device_name_text=(By.ID,"define_name")#輸入設備名稱device_name_id=(By.ID,"define_deviceIds")#關聯設備名稱iddevice_name_xpath=(By.XPATH,"//*[@id='define_deviceIds']")#關聯設備名稱xpath#點擊新增設備組頁面的啟用按鈕enable_xpath_text=(By.XPATH,'//*[@id="define_status"]/label[1]/span[text()="啟用"]')device_type_id=(By.ID,"define_deviceTypeId")#設備關聯的設備類型iddevice_type_xpath=(By.XPATH,"//*[@id='define_deviceTypeId']")#設備關聯的設備類型xpathdevices_type_id=(By.ID,"define_type")#設備組關聯的設備類型iddevices_type_xpath=(By.XPATH,"//*[@id='define_type']")#設備組關聯的設備類型xpathdevice_supplier_text=(By.ID,"define_brandModel")#輸入設備供應商devices_list_menu=(By.XPATH,'//*[text()="設備組列表"]')#點擊設備組列表菜單devices_list_code_text=(By.ID,"define_groupCode")#設備組編碼devices_list_name_text=(By.ID,"define_groupName")#設備組名稱process_route_menu=(By.XPATH,'//*[text()="工藝路線"]')#點擊工藝路線菜單process_route_material_name_id=(By.ID,"define_materialId")#工藝路線關聯的物料idprocess_route_material_name_xpath=(By.XPATH,"//*[@id='define_materialId']")#工藝路線關聯的物料xpathprocess_route_procedure_name_id=(By.ID,"define_procedure")#工藝路線關聯的工序idprocess_route_procedure_name_xpath=(By.XPATH,"//*[@id='define_procedure']")#工藝路線關聯的工序xpathprocess_route_device_name_id=(By.ID,"define_deviceDoList0")#工藝路線關聯的設備idprocess_route_device_name_xpath=(By.XPATH,"//*[@id='define_deviceDoList0']")#工藝路線關聯的設備xpathstandard_box_count_xpath=(By.XPATH,'//*[@id="define_standarNum0"]')#標準框數量xpathdriver=None#使用@classmethod裝飾器,setUpClass和tearDownClass讓每類執行只需要開啟一次瀏覽器即可#使用@classmethod裝飾器時不要把要測試的網頁放置到setUpClass中那樣執行完第一個用例時不會再次打開瀏覽器@classmethoddefsetUpClass(cls):#忽略告警信息warnings.simplefilter('ignore',ResourceWarning)cls.driver=open_browser()cls.driver.implicitly_wait(10)cls.driver.maximize_window()@classmethoddeftearDownClass(cls):cls.driver.quit()if__name__=='__main__':#調用unittest的TestSuite(),理解為管理case的一個容器(測試套件)#unittest框架的自動化測試用例是以0-9、A-Z來排序執行測試用例suite=unittest.TestSuite()runner=unittest.TextTestRunner()
2、新建一個包名:config(用于存放配置文件、讀取配置文件函數、業務變量)
(1)在config包下新建一個config.ini配置文件,作用:通過讀取配置文件來獲取變量。config.py文件代碼如下:
#通過讀取配置文件來獲取變量[sections]url=https://www.baidu.com/
(2)在config包下新建一個read_config.py文件,作用:讀取配置文件信息。read_config.py文件代碼如下:
#coding=utf-8"""------------------------------------@Time:2020/01/15@Auth:Anker@File:read_config.py@purpose:讀取配置文件信息@IDE:PyCharm@Motto:Believeinyourselfandpersistencecanmakesuccess!------------------------------------"""importconfigparserimportosclassReadConf:def__init__(self):current_path=os.path.dirname(os.path.relpath(__file__))#獲取配置文件路徑config_path=os.path.join(current_path,"config.ini")#創建管理對象self.conf=configparser.ConfigParser()#讀ini文件self.conf.read(config_path,encoding="utf-8")defreadConf(self,param):#獲取所有的section#sections=self.conf.sections()#print(sections)#獲取某個sections中的所有值,將其轉化為字典items=dict(self.conf.items(param))returnitemsif__name__=='__main__':test=ReadConf()url=test.readConf("sections")#傳入sections的值print('sections值為:',url)
(3)在config包下新建一個variable.py文件,作用:業務關聯的變量。variable.py文件代碼如下:
#coding=utf-8"""------------------------------------@Time:2020/01/15@Auth:Anker@File:variable.py@purpose:業務關聯的變量@IDE:PyCharm@Motto:Believeinyourselfandpersistencecanmakesuccess!------------------------------------"""importtimeimportrandom#random模塊用于隨機數生成#獲取系統當前時間,并在1~1000中隨機生成一個動態變量數值#date_prefix=time.strftime("%Y-%m-%d%H:%M:%S")+"_編號"+str(random.randint(1,1000))date_prefix=time.strftime("%Y%m%d")+"_編號"+str(random.randint(1,1000))factory_name="中國"+date_prefixfactory_address="浙江"+date_prefixdepartment_name="測試部"+date_prefixworkshop_code="chejian"+date_prefixworkshop_name="車間"+date_prefixworkshop_ip="192.168.1.1"workshop_management="管理員"ipc_name="終端"+date_prefixipc_address="浙江"+date_prefixipc_ip="1"device_type="設備類型"+date_prefixdevice_code="shebei"+date_prefixdevice_name="設備"+date_prefixdevice_group_list_code="設備組編碼"+date_prefixdevice_group_list="設備組"+date_prefixmaterial_name="測試物料"+date_prefixmaterial_code="wuliao"+date_prefixmaterial_code_path='//*[text()="'+material_code+'"]'procedure_name="測試工序"+date_prefixprocess_route="主工藝路線"orderNo="order"+date_prefixfirst_quality_contests="首檢"+date_prefixfirst_quality_types="文本輸入型"patrol_quality_contests="巡檢"+date_prefixpatrol_quality_types="文本輸入型"first_check_programme="首檢方案"+date_prefixpatrol_check_programme="巡檢方案"+date_prefixmould_warehouse="模具倉庫"+date_prefixmould_warehouse_address="中國科技"+date_prefixtools_library="工裝倉庫"+date_prefixtools_library_address="中國科技"+date_prefixmould_storehouse="模具庫位"+date_prefixmould_storehouse_address="中國科技"+date_prefixtool_storehouse="工裝庫位"+date_prefixtool_storehouse_address="中國科技"+date_prefixmould_code="mould"+date_prefixmould_name="模具"+date_prefixdevice_supplier="供應商"+date_prefix
3、新建一個包名:report(用于存放測試報告和發送郵件函數)
(1)在report包下新建一個send_email.py文件,作用:發送郵件。send_email.py文件代碼如下:
#coding=utf-8"""------------------------------------@Time:2020/01/15@Auth:Anker@File:send_email.py@purpose:發送郵件@IDE:PyCharm@Motto:Believeinyourselfandpersistencecanmakesuccess!------------------------------------"""importsmtplibfromemail.mime.multipartimportMIMEMultipartfromemail.mime.textimportMIMETextimportosdefsend_email():'''發送測試報告到郵箱:param::return:'''#----------1.跟發件相關的參數------#發件服務器smtp_server="smtp.qq.com"port=25#端口#發送者賬號sender="456789@qq.com"#發送者密碼password="abc456789"#接收人receiver="456789@qq.com"#----------2.編輯郵件的內容--------#讀文件#os.getcwd()#獲取當前路徑#os.path.abspath('..')#獲取上級路徑,一個.表示上級目錄,兩個.表示上兩級目錄current_path=os.path.abspath('report')#讀取report文件夾里的report.htmlfile_path=os.path.join(current_path,"report.html")withopen(file_path,"rb")asfp:mail_body=fp.read()message=MIMEMultipart()message["from"]=sender#發件人message["to"]=receiver#收件人message["subject"]="UI自動化測試"#主題#正文#通過decode()方法轉換字符body=MIMEText('<h2>大家好:<h2\nh2>UI自動化測試執行結果如下,''詳情請見附件</h2><imgsrc="cid:small">'+mail_body.decode(),"html","utf-8")message.attach(body)#附件enclosure=MIMEText(mail_body,"base64","utf-8")enclosure["Content-Type"]="application/octet-stream"enclosure["Content-Disposition"]='attachment;filename="report.html"'message.attach(enclosure)#----------3.發送郵件--------------try:smtp=smtplib.SMTP()smtp.connect(smtp_server)#連接服務器smtp.login(sender,password)except:smtp=smtplib.SMTP_SSL(smtp_server,port)smtp.login(sender,password)#登錄smtp.sendmail(sender,receiver,message.as_string())#發送smtp.quit()
4、新建一個包名:test_case(用于存放測試用例)
(1)在test_case包下新建一個test_login.py文件,作用:登錄測試用例。test_login.py文件代碼如下:
#coding=utf-8"""------------------------------------@Time:2020/01/15@Auth:Anker@File:test_login.py@purpose:測試用戶登錄@IDE:PyCharm@Motto:Believeinyourselfandpersistencecanmakesuccess!------------------------------------"""importunittestfromcommonimportunitfromcommon.loginimportLoginPageclassLoginTest(unit.Unit):defuser_login_verify(self,username="",password=""):LoginPage(self.driver).login(username,password)deftest_login1(self):'''用戶名、密碼正確'''self.user_login_verify(username="1828888888",password="000000")deftest_login2(self):'''用戶名正確,密碼不正確'''self.user_login_verify(username="1828888888",password="111")deftest_login3(self):'''用戶名不正確,密碼正確'''self.user_login_verify(username="aaa",password="000000")deftest_login4(self):'''用戶名、密碼都不正確'''self.user_login_verify(username="aaa",password="111111")deftest_login5(self):'''用戶名、密碼為空'''self.user_login_verify(username="",password="")deftest_login6(self):'''用戶名為空,密碼不為空'''self.user_login_verify(username="",password="090909")deftest_login7(self):'''用戶名不為空,密碼為空'''self.user_login_verify(username="123",password="")if__name__=='__main__':unittest.main()
(2)在test_case包下新建一個test_PC.py文件,作用:業務測試用例(冒煙測試)。test_PC.py文件代碼如下:
#coding=utf-8"""------------------------------------@Time:2020/01/15@Auth:Anker@File:test_PC.py@purpose:冒煙測試用例@IDE:PyCharm@Motto:Believeinyourselfandpersistencecanmakesuccess!------------------------------------"""importtimefromselenium.webdriver.common.keysimportKeys#獲取鍵盤事件fromcommonimportunitfromcommon.loginimportLoginPagefromconfigimportvariable#導入配置文件里的變量名classTestCase(unit.Unit):deftest_case01_add_factory(self):"""新增工廠"""#調用登錄方法LoginPage(self.driver).login()time.sleep(2)#展開知識圖譜LoginPage(self.driver).find_element(*self.knowledge_graph_menu).click()time.sleep(1)#進入工廠建模頁面LoginPage(self.driver).find_element(*self.factory_modeling_menu).click()time.sleep(1)#點擊"新增"按鈕LoginPage(self.driver).find_element(*self.add_button).click()time.sleep(1)#輸入工廠名稱LoginPage(self.driver).find_element(*self.factory_name_text).send_keys(variable.factory_name)#輸入工廠地址LoginPage(self.driver).find_element(*self.factory_address_text).send_keys(variable.factory_address)#點擊"確定"按鈕LoginPage(self.driver).find_element(*self.confirm_button).click()print("新增的工廠:",variable.factory_name)deftest_case02_add_department(self):"""新增部門"""time.sleep(2)#展開系統管理LoginPage(self.driver).find_element(*self.system_management_menu).click()time.sleep(1)#進入部門管理頁面LoginPage(self.driver).find_element(*self.department_management_menu).click()time.sleep(1)#點擊"新增"按鈕LoginPage(self.driver).find_element(*self.add_button).click()time.sleep(1)#輸入部門名稱LoginPage(self.driver).find_element(*self.department_name_text).send_keys(variable.department_name)time.sleep(1)#關聯的工廠名稱LoginPage(self.driver).find_element(*self.factory_id).click()time.sleep(1)LoginPage(self.driver).find_elements(*self.factory_xpath)[1].send_keys(variable.factory_name)time.sleep(1)LoginPage(self.driver).find_element(*self.enter_xpath).send_keys(Keys.ENTER)time.sleep(1)#點擊“確定”按鈕LoginPage(self.driver).find_element(*self.confirm_button).click()print("新增的部門:",variable.department_name)deftest_case03_add_workshop(self):"""新增車間"""time.sleep(2)#展開知識圖譜LoginPage(self.driver).find_element(*self.knowledge_graph_menu).click()time.sleep(1)#進入工廠建模頁面LoginPage(self.driver).find_element(*self.factory_modeling_menu).click()time.sleep(1)#進入車間定義頁面LoginPage(self.driver).find_element(*self.workshop_definition_menu).click()time.sleep(1)#點擊"新增"按鈕LoginPage(self.driver).find_element(*self.add_button).click()time.sleep(1)#輸入車間編碼LoginPage(self.driver).find_element(*self.workshop_code_text).send_keys(variable.workshop_code)#輸入車間名稱LoginPage(self.driver).find_element(*self.workshop_name_text).send_keys(variable.workshop_name)time.sleep(1)#關聯的部門名稱LoginPage(self.driver).find_element(*self.department_id).click()time.sleep(1)LoginPage(self.driver).find_elements(*self.department_xpath)[1].send_keys(variable.department_name)time.sleep(1)LoginPage(self.driver).find_element(*self.enter_xpath).send_keys(Keys.ENTER)time.sleep(1)#輸入車間IPLoginPage(self.driver).find_element(*self.workshop_ip_text).send_keys(variable.workshop_ip)#輸入車間負責人LoginPage(self.driver).find_element(*self.workshop_management_text).send_keys(variable.workshop_management)#點擊"確定"按鈕LoginPage(self.driver).find_element(*self.confirm_button).click()print("新增的車間:",variable.workshop_name)deftest_case04_add_ipc(self):"""新增終端"""time.sleep(2)#進入終端定義頁面LoginPage(self.driver).find_element(*self.ipc_definition_menu).click()time.sleep(1)#點擊"新增"按鈕LoginPage(self.driver).find_element(*self.add_button).click()time.sleep(1)#輸入終端名稱LoginPage(self.driver).find_element(*self.ipc_name_text).send_keys(variable.ipc_name)#輸入終端地址LoginPage(self.driver).find_element(*self.ipc_address_text).send_keys(variable.ipc_address)#輸入終端ipLoginPage(self.driver).find_element(*self.ipc_ip_text).send_keys(variable.ipc_ip)#輸入終端備注信息LoginPage(self.driver).find_element(*self.ipc_remarks_text).send_keys("測試環境")time.sleep(1)#點擊"確定"按鈕LoginPage(self.driver).find_element(*self.confirm_button).click()print("新增的終端:",variable.ipc_name)print("終端ip:",variable.ipc_ip)deftest_case05_add_device_type(self):"""新增設備類型"""time.sleep(2)#進入設備定義頁面LoginPage(self.driver).find_element(*self.device_definition_menu).click()time.sleep(1)#點擊"新增"按鈕LoginPage(self.driver).find_element(*self.add_button).click()time.sleep(1)#輸入設備類型LoginPage(self.driver).find_element(*self.device_type_text).send_keys(variable.device_type)#點擊"確定"按鈕LoginPage(self.driver).find_element(*self.confirm_button).click()print("新增的設備類型:",variable.device_type)deftest_case06_add_device(self):"""新增設備"""time.sleep(2)#進入設備列表頁面LoginPage(self.driver).find_element(*self.device_list_menu).click()time.sleep(1)#點擊"新增"按鈕LoginPage(self.driver).find_element(*self.add_button).click()time.sleep(1)#輸入設備編碼LoginPage(self.driver).find_element(*self.device_code_text).send_keys(variable.device_code)#輸入設備名稱LoginPage(self.driver).find_element(*self.device_name_text).send_keys(variable.device_name)time.sleep(1)#關聯的設備類型LoginPage(self.driver).find_element(*self.device_type_id).click()time.sleep(1)LoginPage(self.driver).find_elements(*self.device_type_xpath)[1].send_keys(variable.device_type)time.sleep(1)LoginPage(self.driver).find_elements(*self.enter_xpath)[1].send_keys(Keys.ENTER)time.sleep(1)#綁定的工控機LoginPage(self.driver).find_element(*self.ipc_name_id).click()time.sleep(1)LoginPage(self.driver).find_elements(*self.ipc_name_xpath)[1].send_keys(variable.ipc_name)time.sleep(1)LoginPage(self.driver).find_elements(*self.enter_xpath)[2].send_keys(Keys.ENTER)time.sleep(1)#是否采集LoginPage(self.driver).find_element(*self.yes_no_xpath).click()time.sleep(1)#所屬車間LoginPage(self.driver).find_element(*self.workshop_name_id).click()time.sleep(1)LoginPage(self.driver).find_elements(*self.workshop_name_xpath)[1].send_keys(variable.workshop_name)time.sleep(1)LoginPage(self.driver).find_elements(*self.enter_xpath)[3].send_keys(Keys.ENTER)time.sleep(1)#輸入設備供應商LoginPage(self.driver).find_element(*self.device_supplier_text).send_keys(variable.device_supplier)time.sleep(1)#點擊"確定"按鈕LoginPage(self.driver).find_element(*self.confirm_button).click()print("新增的設備:",variable.device_name)print("設備供應商:",variable.device_supplier)deftest_case07_add_device_group_list(self):"""新增設備組"""time.sleep(2)#進入設備組列表頁面LoginPage(self.driver).find_element(*self.devices_list_menu).click()time.sleep(1)#點擊"新增"按鈕LoginPage(self.driver).find_element(*self.add_button).click()time.sleep(1)#輸入設備組編碼LoginPage(self.driver).find_element(*self.devices_list_code_text).send_keys(variable.devices_list_code)#輸入設備組名稱LoginPage(self.driver).find_element(*self.devices_list_name_text).send_keys(variable.devices_list_name)time.sleep(1)#關聯的設備LoginPage(self.driver).find_element(*self.device_name_id).click()time.sleep(1)LoginPage(self.driver).find_elements(*self.device_name_xpath)[1].send_keys(variable.device_name)time.sleep(1)LoginPage(self.driver).find_elements(*self.enter_xpath)[1].send_keys(Keys.ENTER)time.sleep(1)#點擊"啟用"按鈕LoginPage(self.driver).find_element(*self.enable_xpath_text).click()time.sleep(1)#關聯的設備類型LoginPage(self.driver).find_element(*self.devices_type_id).click()time.sleep(1)LoginPage(self.driver).find_elements(*self.devices_type_xpath)[1].send_keys(variable.device_type)time.sleep(1)LoginPage(self.driver).find_elements(*self.enter_xpath)[2].send_keys(Keys.ENTER)time.sleep(1)#綁定的工控機LoginPage(self.driver).find_element(*self.ipc_name_id).click()time.sleep(1)LoginPage(self.driver).find_elements(*self.ipc_name_xpath)[1].send_keys(variable.ipc_name)time.sleep(1)LoginPage(self.driver).find_elements(*self.enter_xpath)[3].send_keys(Keys.ENTER)time.sleep(1)#點擊"啟用"按鈕(再次點擊啟用按鈕的原因是:當選擇綁定的工控機,按回車鍵后,需點擊其它地方,才能將光標跳轉到下個車間選擇框)LoginPage(self.driver).find_element(*self.enable_xpath_text).click()time.sleep(1)#所屬車間LoginPage(self.driver).find_element(*self.workshop_name_id).click()time.sleep(1)LoginPage(self.driver).find_elements(*self.workshop_name_xpath)[1].send_keys(variable.workshop_name)time.sleep(1)LoginPage(self.driver).find_elements(*self.enter_xpath)[4].send_keys(Keys.ENTER)time.sleep(1)#點擊"確定"按鈕LoginPage(self.driver).find_element(*self.confirm_button).click()print("新增的設備組:",variable.devices_list_name)deftest_case08_add_material(self):"""新增物料"""time.sleep(2)#進入物料定義頁面LoginPage(self.driver).find_element(*self.material_definition_menu).click()time.sleep(1)#點擊"新增"按鈕LoginPage(self.driver).find_element(*self.add_button).click()time.sleep(1)#輸入物料名稱LoginPage(self.driver).find_element(*self.material_name_text).send_keys(variable.material_name)#輸入物料編碼LoginPage(self.driver).find_element(*self.material_code_text).send_keys(variable.material_code)#點擊選擇"自制"LoginPage(self.driver).find_element(*self.self_control_xpath).click()#輸入計量單位LoginPage(self.driver).find_element(*self.material_unit_text).send_keys("kg")#點擊"確定"按鈕LoginPage(self.driver).find_element(*self.confirm_button).click()print("新增的物料:",variable.material_name)deftest_case09_add_BOM(self):"""新增BOM"""time.sleep(2)#進入BOM定義頁面LoginPage(self.driver).find_element(*self.BOM_definition_menu).click()time.sleep(1)#點擊"新增"按鈕LoginPage(self.driver).find_element(*self.add_button).click()time.sleep(1)#關聯的物料LoginPage(self.driver).find_element(*self.BOM_material_name_id).click()time.sleep(1)LoginPage(self.driver).find_elements(*self.BOM_material_name_xpath)[1].send_keys(variable.material_name)time.sleep(1)LoginPage(self.driver).find_elements(*self.enter_xpath)[1].send_keys(Keys.ENTER)time.sleep(1)#點擊"確定"按鈕LoginPage(self.driver).find_element(*self.confirm_button).click()deftest_case10_add_procedure(self):"""新增工序"""time.sleep(2)#進入工序定義頁面LoginPage(self.driver).find_element(*self.procedure_definition_menu).click()time.sleep(1)#點擊"新增"按鈕LoginPage(self.driver).find_element(*self.add_button).click()time.sleep(1)#輸入工序名稱LoginPage(self.driver).find_element(*self.procedure_name_text).send_keys(variable.procedure_name)time.sleep(1)#關聯設備類型LoginPage(self.driver).find_element(*self.procedure_device_type_id).click()time.sleep(1)LoginPage(self.driver).find_elements(*self.procedure_device_type_xpath)[1].send_keys(variable.device_type)time.sleep(1)LoginPage(self.driver).find_element(*self.enter_xpath).send_keys(Keys.ENTER)time.sleep(1)#是否使用模具LoginPage(self.driver).find_element(*self.tools_yes_no_xpath).click()time.sleep(1)#點擊"確定"按鈕LoginPage(self.driver).find_element(*self.confirm_button).click()print("新增的工序:",variable.procedure_name)deftest_case11_add_process_route(self):"""新增工藝路線"""standard_box_count=str(variable.random.randint(1,1000))#標準框數量隨機生成time.sleep(2)#進入工藝路線頁面LoginPage(self.driver).find_element(*self.process_route_menu).click()time.sleep(1)#判斷新增的物料是否配置過工藝路線res=LoginPage(self.driver).isElementPresent(variable.material_code_path)ifres:print("該物料已配置工藝路線")time.sleep(1)#跳出工藝路線頁面,進入知識圖譜菜單LoginPage(self.driver).find_element(*self.knowledge_graph_menu).click()else:#點擊"新增"按鈕LoginPage(self.driver).find_element(*self.add_button).click()time.sleep(1)#關聯物料名稱LoginPage(self.driver).find_element(*self.process_route_material_name_id).click()time.sleep(1)LoginPage(self.driver).find_elements(*self.process_route_material_name_xpath)[1].\send_keys(variable.material_name)time.sleep(1)LoginPage(self.driver).find_elements(*self.enter_xpath)[1].send_keys(Keys.ENTER)time.sleep(1)#選擇是否主工藝路線LoginPage(self.driver).find_element(*self.process_route_yes_no_xpath).click()time.sleep(1)#關聯的工序名稱LoginPage(self.driver).find_element(*self.process_route_procedure_name_id).click()time.sleep(1)LoginPage(self.driver).find_elements(*self.process_route_procedure_name_xpath)[1].\send_keys(variable.procedure_name)time.sleep(1)LoginPage(self.driver).find_elements(*self.enter_xpath)[2].send_keys(Keys.ENTER)time.sleep(1)#關聯設備LoginPage(self.driver).find_element(*self.process_route_device_name_id).click()time.sleep(1)LoginPage(self.driver).find_elements(*self.process_route_device_name_xpath)[1].\send_keys(variable.device_name)time.sleep(1)LoginPage(self.driver).find_elements(*self.enter_xpath)[2].send_keys(Keys.ENTER)time.sleep(1)#默認標準框數量LoginPage(self.driver).find_element(*self.standard_box_count_xpath).click()time.sleep(1)LoginPage(self.driver).find_element(*self.standard_box_count_xpath).send_keys(standard_box_count)time.sleep(1)#點擊"確定"按鈕LoginPage(self.driver).find_element(*self.confirm_button).click()
5、新建一個run_all_test_case.py文件,作用:業務測試用例(新增工廠)。run_all_test_case.py文件代碼如下:
#coding=utf-8"""------------------------------------@Time:2020/01/10@Auth:Anker@File:run_all_test_case.py@purpose:執行所有測試用例@IDE:PyCharm@Motto:Believeinyourselfandpersistencecanmakesuccess!------------------------------------"""importunittestfromcommonimportHTMLTestRunnerimportosfromreport.send_emailimportsend_emailcurrent_path=os.getcwd()#當前文件路徑case_path=os.path.join(current_path,"test_case")#用例路徑#存放報告路徑report_path=os.path.join(current_path,"report")#discover找出以test開頭的用例defall_case():discover=unittest.defaultTestLoader.discover(case_path,"test*.py")returndiscoverif__name__=="__main__":#測試報告為report.htmlresult_path=os.path.join(report_path,"report.html")#打開文件,把結果寫進文件中,w,有內容的話,清空了再寫進去fp=open(result_path,"wb")runner=HTMLTestRunner.HTMLTestRunner(stream=fp,title="UI自動化測試報告",description="用例執行情況")#調用all_case函數返回值runner.run(all_case())#關閉剛才打開的文件fp.close()#調用發送郵件方法send_email()
關于如何進行po+selenium+unittest自動化測試項目實戰問題的解答就分享到這里了,希望以上內容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關注本站行業資訊頻道了解更多相關知識。
本文由 貴州做網站公司 整理發布,部分圖文來源于互聯網,如有侵權,請聯系我們刪除,謝謝!
c語言中正確的字符常量是用一對單引號將一個字符括起表示合法的字符常量。例如‘a’。數值包括整型、浮點型。整型可用十進制,八進制,十六進制。八進制前面要加0,后面...
2022年天津專場考試原定于3月19日舉行,受疫情影響確定延期,但目前延期后的考試時間推遲。 符合報名條件的考生,須在規定時間登錄招考資訊網(www.zha...
:喜歡聽,樂意看。指很受歡迎?!巴卣官Y料”喜聞樂見:[ xǐ wén lè jiàn ]詳細解釋1. 【解釋】:喜歡聽,樂意看。指很受歡迎。2. 【示例】:這是...
(資料圖)隨著社會越來越發達,大家都選擇在網絡上汲取相關知識內容,比如刺客信條3劇情簡介,為了更好的解答大家的問題,小編也是翻閱整理了相應內容,下面就一起來看一下吧!《刺客信條3》是法國育碧公司推出的3D動作冒險系列游戲的正統第3代作品?!洞炭托艞l3》的故事背景設定在18世紀中后期的美洲大陸。玩家將扮演名為康納的刺客,在獨立戰爭時期的美國各地展開冒險,并將親歷革命時期的各類重要事件。本作采用了新版...
股市5000點是哪年?股市5000點的意思是上證指數到5000點,上證指數有3次站上5000點,之一次是2007、第二次是2008年,第三次是2015年。第一次:2007年8月23日,上證指數首次站上5000點,而后一路上行,2007年10月16日達到上證指數目前頂峰6124.04點,2007年11月22日站上5000點后,首次跌破5000點。第二次:2008年1月14日,上證指數更高至5522....
新華社???月9日電題:秘魯羊駝“萌”在進博會上走俏。新華社記者田瑞楊冠宇在首屆中國國際消費品博覽會現場,穿行于各國好物間的陳女士在一個擺滿秘魯娃娃的貨架前駐足。在與3歲的女兒視頻通話后,陳女士挑選了一只手工制作的羊駝熊?!半m然有點貴,但是感覺很好,特別可愛。孩子一定很喜歡!”陳女士說。羊駝在秘魯有著極高的經濟價值,羊駝玩偶是具有當地特色的手工藝品。進博會上,陳女士買的熊娃娃來自秘魯品牌Warmp...