Page Object Model(简称PO模式)
PO模式是一种设计模式,实质就是面向对象的设计思想。一般是将页面定位与业务操作分离,只关注业务的实现,而不关注数据的计算。
1、面向过程的代码示例
一个登录模块代码如下:
from selenium import webdriver
broswer = webdriver.Chrome()
broswer.get('http://127.0.0.1:8088/')
# 登录
broswer.find_element_by_name('username').send_keys('user')
broswer.find_element_by_name('password').send_keys('123456')
broswer.find_element_by_css_selector('button').click()
很明显这就是面向过程的代码,当项目不止这一个模块时,缺点就会暴露出来了。
面向过程代码的缺点:
1、代码可读性差,一堆 find_element,杂乱无章
2、扩展性差,用例多了,可能会产生大量重复代码
3、复用性差,缺少公共方法
4、可维护性差,一旦元素变化,需要大面积修改代码
2、PO模式的代码示例
对于上节代码中,需要优化的地方:
- 1、参数(url、用户名、密码等)需要统一放在config文件中,便于管理
- 2、浏览器也不能每个模块都创建一个,这样就不是在同一个页面中操作了,需要将浏览器的创建及其配置放在mydriver文件中
- 3、将所有区块公共的操作可以放在basepage文件中,如:调用步骤2中创建好的浏览器、显示等待等
- 4、元素定位代码和对元素操作的代码要分开
优化后的代码如下:
1、config.py
url = 'http://127.0.0.1:8088'
# 设定用户名、密码
username = 'user'
pwd = '123456'
# 显示等待中,设定超时时间、轮询时间
time_out = 10
poll_time = 0.5
2、mydriver.py
from selenium import webdriver
from config import username,pwd,url
class MyDriver:
driver = None
@classmethod
def get_driver(cls):
if cls.driver is None:
cls.driver = webdriver.Chrome()
# 最大化窗口
cls.driver.maximize_window()
# 访问网址
cls.driver.get(url)
return cls.driver
3、basepage.py
from selenium import webdriver
from mydriver import MyDriver
from config import time_out,poll_time
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
class common:
def __init__(self):
self.driver = MyDriver.get_driver()
# 显示等待,获取元素
def get_element(self,locator):
WebDriverWait(self.driver,time_out,poll_time).until(
EC.visibility_of_element_located(locator)
)
return self.driver.find_element(*locator)
# 显示等待,获取元素列表
def get_elements(self,locator):
WebDriverWait(self.driver,time_out,poll_time).until(
EC.visibility_of_element_located(locator)
)
return self.driver.find_elements(*locator)
4、login.py
from selenium import webdriver
from common import common
from selenium.webdriver.common.by import By
from config import username,pwd,url
class login(common):
# 定位元素
def username_input(self):
return self.get_element((By.NAME,'username'))
def password_input(self):
return self.get_element((By.NAME,'password'))
def login_button(self):
return self.get_element((By.CSS_SELECTOR,'button'))
class loginAnction(login):
# 操作元素
def loginAnction(self):
self.username_input().send_keys(username)
self.password_input().send_keys(pwd)
self.login_button().click()