前言 今天呢笔者想给大家来唠唠pythonselenium的web自动化的PageObject模式解析及案例,废话就不多说了咱们直接进入正题。 一、PO模式 PageObject(简称PO)模式,是Selenium实战中最为流行,并且是自动化测试中最为熟悉和推崇的一种设计模式。在设计自动化测试时,把页面元素和元素的操作方法按照页面抽象出来,分离成一定的对象,然后再进行组织。 做web自动化最头疼的一个问题,莫过于页面变化了,如果没有使用PO设计模式,页面一变化就意味着之前的元素定位甚至元素的操作方法不能用了,需要重新修改。你需要一个一个从测试脚本中把需要修改的元素定位方式、元素的操作方法找出来,然后一一地修改。这样的自动化脚本不但繁琐,维护成本也极高。 而pageobject模式就可以很好地解决这个问题,优点:减少代码冗余业务和实现分离降低维护成本 那到底什么是PageObject模式,见名知意,就是页面对象,在实际自动化测试中,一般对脚本分为三层:对象层:用于存放页面元素定位逻辑层:用于存放一些封装好的功能用例模块业务层:用于存放我们真正的测试用例的操作部分 除了以上三层,还有一个基础层,基础层主要是针对selenium的一些常用方法,根据实际业务需要进行二次封装,如点击、输入等操作加入一些等待、日志输入、截图等操作,方便以后查看脚本的运行情况及问题排查。二、基础层 基础层类名一般命名为BasePage,后续的对象层操作元素时都继承这个基础类,下面以点击、输入为例:basepage。pyimportosimporttimeimportdatetimefromselenium。webdriver。remote。webdriverimportWebDriverfromselenium。webdriver。support。waitimportWebDriverWaitfromselenium。webdriver。supportimportexpectedconditionsasECfromcommon。loggingimportlogfromcommon。constantimportIMGDIRclassBasePage:definit(self,driver:WebDriver):self。driverdriverdefwaitelevisible(self,loc,imgdesc,timeout20,frequency0。5):等待元素可见try:WebDriverWait(self。driver,timeout,frequency)。until(EC。visibilityofelementlocated(loc))log。info(等待:{}元素{}可见成功。。format(imgdesc,loc))except:log。exception(等待:{}元素{}可见失败!。format(imgdesc,loc))self。saveimg(imgdesc)raisedefgetelement(self,loc,imgdesc):查找元素try:eleself。driver。findelement(loc)except:log。exception(查找:{}元素{}失败!。format(imgdesc,loc))self。saveimg(imgdesc)raiseelse:log。info(查找:{}元素{}成功。format(imgdesc,loc))returneledefclickelement(self,loc,imgdesc,timeout20,frequency0。5):点击元素self。waitelevisible(loc,imgdesc,timeout,frequency)eleself。getelement(loc,imgdesc)try:ele。click()log。info(点击:{}元素{}成功。format(imgdesc,loc))except:log。exception(点击:{}元素{}失败!。format(imgdesc,loc))self。saveimg(imgdesc)raisedefinputtext(self,loc,value,imgdesc,timeout20,frequency0。5):在元素中输入文本self。waitelevisible(loc,imgdesc,timeout,frequency)eleself。getelement(loc,imgdesc)try:ele。sendkeys(value)log。info(输入:在{}元素{}输入文本值({})成功。format(imgdesc,loc,value))except:log。exception(输入:在{}元素{}输入文本值({})失败!。format(imgdesc,loc,value))self。saveimg(imgdesc)raisedefsaveimg(self,imgdescription):保存异常截图nowtime。strftime(YmdHMS,time。localtime())imgpathos。path。join(IMGDIR,nowimgdescription。png)try:self。driver。savescreenshot(imgpath)except:log。exception(异常截图失败!)else:log。info(异常截图成功,截图存放在{}。format(imgpath))折叠 以点击clickelement()为例,这里二次封装时加入了等待操作、日志输入、异常截图,后面点击元素时就直接调用clickelement()就可以一步到位,不需要再考虑等待、日志、异常的情况,这里都已经处理好了,虽然在初期写基础页面会比较耗时,但只要基础打好,在后续维护工作中会轻松很多。以上只是一个示例,可以根据自己的实际需要进行优化。三、对象层及逻辑层 对象层存放页面元素定位,逻辑层存放元素操作方法(页面功能),元素定位可以根据实际需要,可以单独放在一个模块来维护,也可以存放在excel中进行集中管理;下面演示的是元素定位和元素操作方法都存放到一个模块中,一个页面一个模块,后续页面元素发生变化,只需要修改在这个模块中修改对应的定位表达式或者操作方法即可。 演示以百度首页为例:baidupage。pyfromselenium。webdriver。common。byimportByfromcommon。basepageimportBasePageclassLoginPage(BasePage):loginbtn(By。XPATH,p〔idu1〕a〔nametjlogin〕)登录按钮usernameloginbtn(By。ID,TANGRAMPSP11footerULoginBtn)用户名登录按钮userinput(By。ID,TANGRAMPSP11userName)用户信息输入框pwdinput(By。ID,TANGRAMPSP11password)密码输入框loginsubmit(By。ID,TANGRAMPSP11submit)登录提交按钮deflogin(self,user,pwd):百度用户名登录:paramuser:手机邮箱用户名:parampwd:密码:return:self。clickelement(self。loginbtn,百度登录)self。clickelement(self。usernameloginbtn,百度登录用户名登录)self。inputtext(self。userinput,user,用户名登录手机邮箱用户名)self。inputtext(self。pwdinput,pwd,用户名登录密码)self。clickelement(self。loginsubmit,用户名登录登录)四、业务层 用于存放真正的测试用例操作,这里不会出现元素定位、页面功能,所有操作都是直接调用逻辑层的。 测试用例测试对象的功能测试数据,下面以百度登录为例(用于演示,简略写的):importunittestimportpytestimportddtfromseleniumimportwebdriverfromPageObjects。baiduloginpageimportLoginPagefromtestdatasimportcommondatasascomdfromtestdatasimportlogindataaslodfromcommon。loggingimportlogddt。ddtclassTestLogin(unittest。TestCase):defsetUp(self):log。info(用例前置工作:打开浏览器)self。driverwebdriver。Chrome()self。driver。get(comd。baiduurl)self。driver。maximizewindow()deftearDown(self):self。driver。quit()log。info(用例后置工作:关闭浏览器)pytest。mark。smokedeftestloginsuccess(self):用例:登录页的登录功能步骤LoginPage(self。driver)。login(lod。successdata〔user〕,lod。successdata〔pwd〕)断言。。。。。 运行结果:Testingstartedat11:50。。。C:softwarepythonpython。exeC:ProgramFilesJetBrainsPyCharmCommunityEdition2022。1。3helperspycharmjbunittestrunner。pypathD:learntesttestcasestestbaidulogin。pyLaunchingunittestswithargumentspythonmunittestD:learntesttestcasestestbaidulogin。pyinD:learnestestcasesProcessfinishedwithexitcode02022071111:50:47,238【testbaidulogin。pyline:27】INFO:用例前置工作:打开浏览器2022071111:50:51,327【basepage。pyline:38】INFO:等待:百度登录元素(xpath,p〔idu1〕a〔nametjlogin〕)可见成功,耗时0:00:00。056843秒2022071111:50:51,339【basepage。pyline:77】INFO:查找:百度登录元素(xpath,p〔idu1〕a〔nametjlogin〕)成功2022071111:50:51,414【basepage。pyline:86】INFO:点击:百度登录元素(xpath,p〔idu1〕a〔nametjlogin〕)成功2022071111:50:53,463【basepage。pyline:38】INFO:等待:百度登录用户名登录元素(id,TANGRAMPSP11footerULoginBtn)可见成功,耗时0:00:02。048293秒2022071111:50:53,474【basepage。pyline:77】INFO:查找:百度登录用户名登录元素(id,TANGRAMPSP11footerULoginBtn)成功2022071111:50:53,535【basepage。pyline:86】INFO:点击:百度登录用户名登录元素(id,TANGRAMPSP11footerULoginBtn)成功2022071111:50:53,576【basepage。pyline:38】INFO:等待:用户名登录手机邮箱用户名元素(id,TANGRAMPSP11userName)可见成功,耗时0:00:00。040890秒2022071111:50:53,584【basepage。pyline:77】INFO:查找:用户名登录手机邮箱用户名元素(id,TANGRAMPSP11userName)成功2022071111:50:53,714【basepage。pyline:98】INFO:输入:在用户名登录手机邮箱用户名元素(id,TANGRAMPSP11userName)输入文本值(15692004245)成功2022071111:50:53,759【basepage。pyline:38】INFO:等待:用户名登录密码元素(id,TANGRAMPSP11password)可见成功,耗时0:00:00。043882秒2022071111:50:53,771【basepage。pyline:77】INFO:查找:用户名登录密码元素(id,TANGRAMPSP11password)成功2022071111:50:53,925【basepage。pyline:98】INFO:输入:在用户名登录密码元素(id,TANGRAMPSP11password)输入文本值(phang0209)成功2022071111:50:53,958【basepage。pyline:38】INFO:等待:用户名登录登录元素(id,TANGRAMPSP11submit)可见成功,耗时0:00:00。031914秒2022071111:50:53,969【basepage。pyline:77】INFO:查找:用户名登录登录元素(id,TANGRAMPSP11submit)成功2022071111:50:54,051【basepage。pyline:86】INFO:点击:用户名登录登录元素(id,TANGRAMPSP11submit)成功2022071111:50:56,426【testbaidulogin。pyline:35】INFO:用例后置工作:关闭浏览器Ran1testin9。191sOK 从输出日志来看,每一步操作都清晰可见,出现问题也能快速定位,这些都可以根据实际需要来优化。PO模式基础层对象层及逻辑层业务层总结 今天的文章就到这里了哟,喜欢的小伙伴记得点赞收藏评论加关注哟。