PO模式:Page Object,是一种页面对象设计模式,算是一种比较好的设计模式。在该设计模式中,功能类(PageObjects)所代表的是每个页面之间的逻辑关系。
PO设计模式
一、PO设计模式的优点
PO模式有以下优点:
1、可以减少了代码的重复编写。
2、PO模式把页面元素定位和业务操作流程分开,界面元素的变化则不需要修改业务逻辑代码。
3、 PO能提高代码的可读性,高复用性,可维护性。
二、非PO设计模式
为了更好地进行对比分析,我们先看看非PO设计模式:
test_logintest.py代码,直接执行所有的流程操作,不做任何封装
from time import sleep
import pytest
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
class Test_logintest():
-
def test_1(self): -
driver=webdriver.Firefox() -
driver.get("http://10.5.1.247/dvwa/login.php") -
sleep(1) -
driver.find_element_by_name("username").send_keys("admin") -
driver.find_element_by_name("password").send_keys("password") -
driver.find_element_by_name("Login").click() -
sleep(2) -
driver.find_element_by_link_text("XSS (Reflected)").click() -
sleep(2) -
driver.find_element_by_name("name").send_keys("nick") -
sleep(1) -
driver.find_element_by_xpath("//input[@value='Submit']").click() -
sleep(1)
if name == ‘main’:
pytest.main(["-sq", "test_logintest.py"])
三、PO设计模式
接下来我们看看PO设计模式
基础层:打开浏览器、封装元素定位
BasePage.py代码:
from selenium.webdriver.common.by import By
class BasePage(object):
-
def __init__(self,driver,url=None): -
self.driver=driver -
self.url=url -
if self.url!=None: -
self.driver.get(self.url) -
def by_name(self,id): -
locator=(By.NAME,id) -
ele=self.driver.find_element(*locator) -
return ele -
def by_linktext(self,linktext): -
locator=(By.LINK_TEXT,linktext) -
ele=self.driver.find_element(*locator) -
return ele -
def by_xpath(self,xpath): -
locator=(By.XPATH,xpath) -
ele=self.driver.find_element(*locator) -
return ele
PO层:页面元素获取,页面基础操作
DvwaPage.py代码:
from time import sleep
from myPytest.test_case.BasePage import *
class DvwaPage(BasePage):
-
def usernameText(self): -
ele=self.by_name("username") -
return ele -
def passwordText(self): -
ele=self.by_name("password") -
return ele -
def linkText(self): -
ele=self.by_linktext("XSS (Reflected)") -
return ele -
def Submit(self): -
ele =self.by_name("Login") -
return ele -
def login_dvwa(self,username,password): -
self.usernameText().send_keys(username) -
self.passwordText().send_keys(password) -
self.Submit().click() -
sleep(2) -
def search(self,str): -
#这里是通过调用linkText方法 -
self.linkText().click() -
#这里是直接调用by_name函数 -
self.by_name("name").send_keys(str) -
sleep(1) -
# 这里是直接调用by_xpath函数 -
self.by_xpath("//input[@value='Submit']").click() -
sleep(1)
运行
运行
测试用例层:业务逻辑和数据驱动的执行
test_loginDvwa.py代码:
import pytest
from myPytest.test_case.DvwaPage import *
from selenium import webdriver
class Test_loginDvwa():
-
def test_login(self): -
self.driver=webdriver.Firefox() -
self.url="http://10.5.1.247/dvwa/login.php" -
username="admin" -
password="password" -
sr=DvwaPage(self.driver,self.url) -
sr.login_dvwa(username,password) -
sr.search("nick")
if name == ‘main’:
pytest.main(["-sq", "test_loginDvwa.py"])
执行结果如下:

四、错误原因排查
我在执行代码时,会出现TypeError: ‘module’ object is not callable这个错误
程序代码 :
import pytest
from myPytest.test_case import DvwaPage
from selenium import webdriver
class Test_loginDvwa():
-
def test_login(self): -
self.driver=webdriver.Firefox() -
self.url="http://10.5.1.247/dvwa/login.php" -
username="admin" -
password="password" -
sr=DvwaPage(self.driver,self.url) -
sr.login_dvwa(username,password) -
sr.search("nick")
执行代码后会报错:
sr=DvwaPage(self.driver,self.url)
E TypeError: ‘module’ object is not callable
原因分析:
Python导入模块的方法有两种:import 模块 和 from 模块 import *,前者导入后,在使用时需加上模块名的限定,而后者则不需要。
解决方式:
from myPytest.test_case import DvwaPage
sr=DvwaPage.DvwaPage(self.driver,self.url)
或
from myPytest.test_case.DvwaPage import *
sr=DvwaPage(self.driver,self.url)
总结:
感谢每一个认真阅读我文章的人!!!
作为一位过来人也是希望大家少走一些弯路,如果你不想再体验一次学习时找不到资料,没人解答问题,坚持几天便放弃的感受的话,在这里我给大家分享一些自动化测试的学习资源,希望能给你前进的路上带来帮助。

软件测试面试文档
我们学习必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有字节大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。


视频文档获取方式:
这份文档和视频资料,对于想从事【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴我走过了最艰难的路程,希望也能帮助到你!以上均可以分享,点下方小卡片即可自行领取。



















