po模型介绍
在自动化中, Selenium 自动化测试中有一个名字经常被提及 PageObject( 思想与面向对象的特征相
同 ) ,通常 PO 模型可以大大提高测试用例的维护效率
优点:重用,业务和对象分离,代码结构清晰,方便代码维护
PageObject设计模式
po的核心要素
- 在 PO 模式中抽离封装集成一个 BasePage 类,该基类应该拥有一个只实现 webdriver 实例的属性
2.每一个 page 都继承 BasePage ,通过 driver 来管理本 page 中元素,将 page 中的操作封装成一个个方法
3.TestCase 继承 unittest.Testcase 类,并依赖 page 类,从而实现相应的测试步骤
非po实现
代码展示
from selenium import webdriver
from time import sleep
driver = webdriver.Firefox()
driver.get("http://www.baidu.com")
driver.find_element_by_id("kw").send_keys("jack")
sleep(1)
driver.find_element_by_id("su").click()
sleep(2)
driver.quit()
代码分析
不同的运行脚本环境,游览器不同:驱动webdriver.Firefox()可以剥离
请求地址的变化(生产环境和测试环境):url = http://www.baidu.com可以剥离
操作元素时,常常要等待元素加载完成方可进行操作:可以把webdriver提供的find_element*方法封
装,在元素操作前,先判断元素是否可以操作
实际测试场景中,可能有多个测试场景,如果每个测试场景都需要维护url,游览器驱动,元素定位等,效
率会非常低
因此基于以上分析,是否可以设计一个所有测试界面(selenium本身是B/S系统开展测试)的基类,来
维护公共的方法,此处定义名字为BasePage.py,用于存放页面公共方法及webdriver原有方法二次封装等。
po是实现
BasePage代码是实现
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains #鼠标操作
class BasePage():
'''BasePage封装所有界面都公用的方法。例如driver,find_element等'''
'''实例化BasePage类时,事先执行的__init__方法,该方法需要传递参数'''
def __init__(self,driver):
self.driver = driver
# 进入网址
def get(self,url):
self.driver.get(url)
#元素定位,替代八大定位
def get_element(self,*locator):
return self.driver.find_element(*locator)
#点击
def left_click(self,*locator):
ActionChains(self.driver).click(self.get_element(*locator)).perform()
#输入
def send_text(self,text,*locator):
self.driver.find_element(*locator).send_keys(text)
#清除
def clear_text(self,*locator):
self.driver.find_element(*locator).clear()
#表单切换
def switch_iframe(self,*locator):
self.driver.switch_to.frame(self.driver.find_element(*locator))
#窗口切换
def switch_window(self,n):
self.driver.switch_to.window(self.driver.window_handles[n])
实现SearchPage
SearchPage代码实现
'''
实现步骤:(1)继承basepage,(2)元素传参,(3)调取方法
'''
from selenium.webdriver.common.by import By
from pomodel.Base.base_page import BasePage
class Search(BasePage):
def __init__(self,driver):
BasePage.__init__(self,driver)
#进入百度
def open_baidu(self,url):
self.get(url)
#输入搜索内容
def input_search_content(self,text):
self.send_text(text,By.ID,"kw")
#点击按钮
def click_baidu_search(self):
self.left_click(By.ID,"su")
实现TestCase
TestCase代码
import unittest
from selenium import webdriver
from pomodel.Pages.search_pages import Search
class BaiBu(unittest.TestCase):
def setUp(self) -> None:
self.driver = webdriver.Firefox()
self.driver.implicitly_wait(10)
def test_serach(self):
url="http://www.baidu.com"
s = Search(self.driver)
s.open_baidu(url)
s.input_search_content("jack")
s.click_baidu_search()
def tearDown(self) -> None:
self.driver.quit()
if __name__ == '__main__':
unittest.main()
生成测试报告
from data.HTMLTestRunner import HTMLTestRunner
from testdemo.test001 import TestClass
import unittest
class UseHtml():
def testmethod(self):
suite = unittest.TestSuite()
lists = ["test001","test002"]
for list_i in lists:
suite.addTest(TestClass(list_i))
with open("../report.html", "wb") as f:
HTMLTestRunner(
stream=f,
title="单元测试",
description="测试一期",
verbosity=2
).run(suite)
uh =UseHtml()
uh.testmethod()
整体操作
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains #鼠标操作
class BasePage():
'''BasePage封装所有界面都公用的方法。例如driver,find_element等'''
'''实例化BasePage类时,事先执行的__init__方法,该方法需要传递参数'''
def __init__(self,driver):
self.driver = driver
# 进入网址
def get(self,url):
self.driver.get(url)
#元素定位,替代八大定位
def get_element(self,*locator):
return self.driver.find_element(*locator)
#点击
def left_click(self,*locator):
ActionChains(self.driver).click(self.get_element(*locator)).perform()
#输入
def send_text(self,text,*locator):
self.driver.find_element(*locator).send_keys(text)
#清除
def clear_text(self,*locator):
self.driver.find_element(*locator).clear()
#表单切换
def switch_iframe(self,*locator):
self.driver.switch_to.frame(self.driver.find_element(*locator))
#窗口切换
def switch_window(self,n):
self.driver.switch_to.window(self.driver.window_handles[n])
from basepagedemo.basepage import BasePage
from selenium.webdriver.common.by import By
class OneClass(BasePage):
def __init__(self,driver):
BasePage.__init__(self,driver)
# 访问百度
def enter_baidu(self,url):
self.get(url)
# 输入12306
def send_message(self,text):
self.send_text(text,By.ID,"kw")
# 点击百度一下
def click_baidu_one(self):
self.left_click(By.ID,"su")
# 点击中国铁路12306
def clike_chinatrain(self):
self.left_click(By.XPATH,'//*[@id="1"]/h3/a[1]')
# 多窗口跳转
def duo_window_switch(self):
self.switch_window(1)
from basepagedemo.basepage import BasePage
from selenium.webdriver.common.by import By
class TwoClass(BasePage):
def __init__(self,driver):
BasePage.__init__(self,driver)
def click_chufadi(self):
self.left_click(By.XPATH,'//*[@id="toolbar_Div"]/div[3]/div[2]/div/div[1]/div/div[2]/div[1]/div[1]/div[1]/div[1]/label')
def chose_chufadi(self):
self.left_click(By.XPATH,'//*[@id="ul_list1"]/li[1]')
def click_daodadi(self):
self.left_click(By.XPATH,'//*[@id="toolbar_Div"]/div[3]/div[2]/div/div[1]/div/div[2]/div[1]/div[1]/div[1]/div[2]/label')
def chose_daodadi(self):
self.left_click(By.XPATH,'//*[@id="ul_list1"]/li[2]')
def click_select_button(self):
self.left_click(By.ID,'search_one')
import unittest,time
from selenium import webdriver
from pages.onepage import OneClass
from pages.twopage import TwoClass
class TestClass(unittest.TestCase):
@classmethod
def setUpClass(cls) -> None:
cls.driver= webdriver.Chrome(r'F:\lianx\po20220111\chromedriver.exe')
cls.driver.implicitly_wait(30)
cls.driver.maximize_window()
def test001(self):
oc = OneClass(self.driver)
oc.enter_baidu("https://www.baidu.com") #访问百度
oc.send_message(12306) #输入框中输入12306
oc.click_baidu_one()
oc.clike_chinatrain()
oc.duo_window_switch()
def test002(self):
tc = TwoClass(self.driver)
tc.click_chufadi()
tc.chose_chufadi()
tc.click_daodadi()
tc.chose_daodadi()
tc.click_select_button()
@classmethod
def tearDownClass(cls) -> None:
time.sleep(4)
cls.driver.quit()
if __name__=='__main':
unittest.main()