web自动化-Page Object模式
一. 原理
1.1 PageObjects
将页面的元素定位和元素行为封装成一个page类,实现页面对象和测试用例分离;如login_page.py
类的属性:元素定位
类的行为:元素的操作;每个行为均要单独定义一个方法,提高串联的复用性。
1.2 TestDatas
测试数据:将测试数据封装;如login_testdatas.py
1.3 TestCases
测试用例:调用所需页面对象中的行为,组成测试用例;如test_login.py
每个用例都单独启动driver去执行,保证用例的独立性/可执行性,用例串联不影响,防止关联时哪个步骤错误影响执行结果。
每个用例共用一个driver,每个用例都单独启动浏览器且结束后关闭浏览器;用例独立,互不影响!
二. 好处
1. 当某个页面的元素发生变化,只需要修改该页面对象中的代码即可,测试用例不需要修改
如登录页面,用户名输入框定位表达式变化,只需修改login_page.py的元素定位表达式
2. 提高代码重用率,结构清晰,维护代码更容易
3. 测试用例发生变化时,不需要或者只需要修改少数页面对象代码即可
三. 分析
四、BasePage基类
4.1 在页面对象中,不难发现,有许多方法是重复在使用的,如,显性等待、find_element、滚动条等;避免冗余,我们可以写一个基类BasePage将这些公共方法提取
定义一个BagePage基类 - BasePage.py
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
import time
class BasePage:
def __init__(self, driver):
self.driver = driver
#等待元素可见
def wait_eleVisible(self,locator,by=By.XPATH,waitTime=50):
#判断by这个默认参数,是否在By(object),webelement的8种方式之内
if by not in By.__dict__.values():
print("定位元素表达式不支持,请检查确认!")
raise Exception
WebDriverWait(self.driver,waitTime).until(EC.visibility_of_element_located((by,locator)))
# 等待元素存在
def wait_elePresence(self, locator, by=By.XPATH, waitTime=50):
# 判断by这个默认参数,是否在By(object),webelement的8种方式之内
if by not in By.__dict__.values():
print("定位元素表达式不支持,请检查确认!")
raise Exception
#等待之前-加个时间
WebDriverWait(self.driver, waitTime).until(EC.presence_of_element_located((by, locator)))
#等待之后-加个时间
#计算等待的时长
#查找一个元素
def find_element(self,locator,by=By.XPATH,waitTime=50):
#等待 - 调用wait_eleVisible方法
self.wait_eleVisible(locator,by,waitTime)
time.sleep(0.5)
#查找 - 返回元素对象
return self.driver.find_element(by,locator) #find_element_by_xpath方法也是内部调用find_element
#查找一组元素
def find_elements(self,locator,by=By.XPATH,waitTime=50):
#等待 - 调用wait_eleVisible方法
self.wait_eleVisible(locator,by,waitTime)
time.sleep(0.5)
#查找 - 返回元素对象
return self.driver.find_elements(by,locator)
#滚动条操作
def scroll_intoView(self,ele):
# 滚动到可见区域-找到该元素,执行js语句
self.driver.execute_script("arguments[0].scrollIntoView();",ele)
time.sleep(0.3)
如:登录页面继承 - login_page.py;直接调用基类的方法,
#引入基类
from WEB_Framework.PageObjects.BasePage import BasePage
#继承
class LoginPage(BasePage):
#登录页面定位表达式
login_username_xpath = '//input[@name="phone"]'
login_passwd_xpath = '//input[@name="password"]'
login_button_xpath = '//button[text()="登录"]'
#账号为空的错误提示
loginError_defaultInfo_xpath = '//div[@class="form-error-info"]'
#登录 -- 成功登录
def login(self,username,passwd):
self.find_element(self.login_username_xpath).send_keys(username)
self.find_element(self.login_passwd_xpath).send_keys(passwd)
self.find_element(self.login_button_xpath).click()
#登录 -- 从登录区域获取错误提示
def get_errorInfo_from_loginArea(self):
errorInfo = self.find_element(self.loginError_defaultInfo_xpath).text
return errorInfo