在编写UI自动化脚本过程,需要考虑如何编写才能使脚本更容易维护及复用率更高,可读性更高。page object(以下称:PO模式)设计模式是Selenium 自动化测试项目开发实践的最佳设计模式之一,其核心思想就是将测试对象及测试脚本分层处理,对界面交互细节的封装,这样可以使测试案例更关注与业务而非界面细节,提高测试案例的可读性。在搭建ui自动化框架,使用的是po设计模式,也就是把每一个页面所需要操作的元素和步骤都封装成一个页面类中。然后使用selenium+unittest搭建
四层框架实现数据、脚本、业务逻辑分离(关键字驱动)。其中四层框架包括基础层(BasePage)、业务逻辑层(Pages)、数据层(Data)、测试用例层(Testcase)
1.基础层(BasePage)
设计一个基本的Page类,所有页面皆继承该类。提供一个页面需要实现的基本功能及公共方法。封装底层操作
2.业务逻辑层(Pages),也叫元素和操作层
按照PO设计模式,将每个页面抽象为一个类,放在Pages包里面,每个页面继承Basepage,可调用Data层数据,包括页面所有的操作对象属性和实现的功能。
3.数据层(Data)
该层存放相关数据,例如:用户数据和密码。在测试用例可通过调用数层的数据来进行操作。
4.测试用例层(Testcases)
每一个测试用例testcase都对应Pages里面的一个页面,继承unnitest.TestCase类。通过调用对应页面类的方法,数据层的数据、增加断言(assert)来验证功能的正确性。此外通过Jenkins自动执行测试、代码质量检测和部署到测试服务器、部署到生产服务器上
在PO模式中一个用例脚目录结构如下:
三.代码介绍
page基类:
from selenium import webdriver
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.common.by import By
class Page():
def __init__(self,driver):
self.driver = driver
def open(self,url):
self.driver.get(url)
self.driver.maximize_window()
def find_element(self,*loc):
try:
wait = WebDriverWait(self.driver,timeout = 10)
wait.until(lambda x:x.find_element(*loc).is_displayed())
return self.driver.find_element(*loc)
except TimeoutException:
raise "Time out"
def find_elements(self,*loc):
try:
wait = WebDriverWait(self.driver,timeout = 10)
wait.until(lambda x:x.find_elements(*loc).is_displayed())
return self.driver.find_elements(*loc)
except TimeoutException:
raise "Time out"
def switch_iframe(self,*loc):
name = self.driver.find_element(*loc)
self.driver.switch_to_frame(name)
def exit(self):
self.driver.quit()
loginpage中放置元素和操作层
from selenium import webdriver
from selenium.webdriver.common.by import By
import time as t
from basic.page import Page
class LoginPage(Page):
_iframe_loc = (By.XPATH,"//div[@id='normalLoginTab']/div[0]/div[0]/iframe")
_user_loc = (By.XPATH,'//input[@name="email" and @data-loginname="loginEmail"]')
_paw_loc = (By.XPATH,'//input[@name="password" and @placeholder="输入密码"]')
_logbt_loc = (By.ID,"dologin")
def user_input(self,username):
self.switch_iframe(*self._iframe_loc)
self.find_element(*self._user_loc).send_key(username)
return username
def paw_input(self,password):
self.find_element(*self._paw_loc).send_key(password)
def login_button(self):
self.find_element(*self._logbt_loc).click()
test_login放置用例层
from elementpage.loginpage import LoginPage
from selenium import webdriver
from basic.page import Page
import time
class TestLogin():
def login(self,driver,url,username,password):
"""
:param driver: driver
:param url: url
:param username: 用户名
:param password: 密码
:return:
"""
obj = Page(driver)
obj.open(url) #输入URL
lobj = LoginPage(driver)
lobj.user_input(username) #录入用户名
lobj.paw_input(password) #录入密码
lobj.login_button() #点击登录
obj.exit()