Python+Selenium+PO模型实现自动化测试

x33g5p2x  于2021-10-25 转载在 Python  
字(6.3k)|赞(0)|评价(0)|浏览(525)

一. PO模型介绍

在自动化中,Selenium自动化测试中有一个名字经常被提及PageObject(思想与面向对象的特征相 同),通常PO模型可以大大提高测试用例的维护效率
PO模型又叫PO设计模式,是selenium自动化测试中最佳的设计模式之一,主要体现在对界面交互细节的封装,将页面定位和业务操作分开,也就是把对象的定位和测试脚本分开,在实际测试中只需要关注业务流程,从而提高可维护性。

优点:
重用,业务和对象分离,代码结构清晰,减少了代码的重复,方便代码维护

缺点:
造成项目结构比较复杂(因为是根据流程进行了模块化处理)

总结:PO模型实现过程是:通过面向对象的方式,对页面定位和页面操作进行分离封装(解耦合,方便后续维护)。

二. PageObject设计模式

三:PO的核心要素

1.在PO模式中抽离封装集成一个BasePage类,该基类应该拥有一个只实现webdriver实例的属性
2.每一个page都继承BasePage,通过driver来管理本page中元素,将page中的操作封装成一个个方法
3.TestCase继承unittest.Testcase类,并依赖page类,从而实现相应的测试步骤

四:代码实现淘宝将手机加入购物车

1.提供一个basepage类

from selenium.webdriver.common.action_chains import ActionChains # 鼠标点击操作
from selenium.webdriver.support.ui import WebDriverWait # 显示等待
from selenium.webdriver.support import expected_conditions as EC # 判断所需要的元素是否已经被加载出来

'''BasePage封装所有界面都公用的方法。例如driver,find_element等'''
class BasePage():
    # 实例化
    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.iframe(self.driver.find_element(*locator))
    # 窗口切换
    def switch_window(self,n):
        self.driver.switch_to.window(self.driver.window_handles[n])
    # 显示等待
    def find_element_by_wait(self, *locator):
        element = WebDriverWait(self.driver, 10, 0.5).until(EC.presence_of_all_elements_located((locator[0], locator[1])))
        return element

2.提供多个page(界面操作)

page1:在游览器中访问百度

from taobao.basepage.base_page import BasePage

class OpenBDPage(BasePage):
    # 初始化BsePage类的驱动
    def __init__(self,driver):
        BasePage.__init__(self,driver)
    # 打开百度
    def open_baidu(self,url):
        self.get(url)

page2:在百度输入淘宝并点击

from taobao.basepage.base_page import BasePage
from selenium.webdriver.common.by import By

class SearchBDPage(BasePage):
    # 初始化BsePage类的驱动
    def __init__(self,driver):
        BasePage.__init__(self,driver)
    # 百度的输入框
    def input_data(self,text):
        self.send_text(text,By.ID,'kw')
    # 点击百度一下
    def click_baidu(self):
        self.left_click(By.ID,'su')
    # 点击 淘 我喜欢
    def click_taobao(self):
        self.left_click(By.XPATH,".//*[@id='1']/h3/a[1]")

page3:多标签处理,点击登录扫描二维码

from po.Base.base_page6 import BasePage
from selenium.webdriver.common.by import By

class WindowBDPage(BasePage):
    # 初始化BsePage类的驱动
    def __init__(self,driver):
        BasePage.__init__(self,driver)
    # 多标签操作
    def switch_window_taobao(self,n):
        self.switch_window(1)
    # 点击亲,请登录
    def click_login(self):
        self.left_click(By.CSS_SELECTOR,"a.h:nth-child(1)")
    # 点击二维码
    def click_qrcode(self):
        self.left_click(By.CSS_SELECTOR,".icon-qrcode")

page4:搜索商品,选择包邮,筛选价格,选择手机

from po.Base.base_page6 import BasePage
from selenium.webdriver.common.by import By

class TaoBaoPage(BasePage):
    # 初始化BsePage类的驱动
    def __init__(self,driver):
        BasePage.__init__(self,driver)
    # 淘宝内的输入
    def input_data(self,text):
        self.send_text(text,By.ID,'q')
    # 点击搜索
    def click_search(self):
        self.left_click(By.CSS_SELECTOR,".btn-search")
    # 点击包邮
    def click_baoyou(self):
        self.left_click(By.CSS_SELECTOR,"a.filter:nth-child(1) > span:nth-child(1)")
    # 输入最低价格
    def send_min_price(self,text):
        self.send_text(text,By.CSS_SELECTOR,"div.inputs:nth-child(1) > div:nth-child(1) > ul:nth-child(1) > li:nth-child(1) > input:nth-child(1)")
    # 输入最高价格
    def send_max_price(self,text):
        self.send_text(text,By.CSS_SELECTOR,"div.inputs:nth-child(1) > div:nth-child(1) > ul:nth-child(1) > li:nth-child(3) > input:nth-child(1)")
    # 点击确定
    def click_confirm(self):
        self.left_click(By.CSS_SELECTOR,".J_SortbarPriceSubmit")
    # 点击选择手机
    def click_phone(self):
        self.left_click(By.CSS_SELECTOR,"#J_Itemlist_Pic_653968396721")

page5:多标签处理,选择颜色,容量,加入购物车并查看

from po.Base.base_page6 import BasePage
from selenium.webdriver.common.by import By

class WindowTBPage(BasePage):
    # 初始化BsePage类的驱动
    def __init__(self, driver):
        BasePage.__init__(self, driver)
    # 多标签操作
    def switch_window_phone(self, n):
        self.switch_window(2)
    # 点击机身颜色
    def click_color(self):
        self.left_click(By.CSS_SELECTOR,"li.tb-txt:nth-child(15) > a:nth-child(1) > span:nth-child(1)")
    # 点击存储容量
    def click_store(self):
        self.left_click(By.CSS_SELECTOR,"dl.J_Prop:nth-child(3) > dd:nth-child(2) > ul:nth-child(1) > li:nth-child(4) > a:nth-child(1) > span:nth-child(1)")
    # 点击加入购物车
    def click_shoping(self):
        self.left_click(By.CSS_SELECTOR,".J_LinkAdd")
    # 点击购物车查看
    def click_shopping_car(self):
        self.left_click(By.CSS_SELECTOR,"#mc-menu-hd > span:nth-child(2)")

3.单元测试

执行测试用例的前置、后置条件,写测试用例,进行实例化,调用方法

import unittest
from selenium import webdriver
from taobao.pages.page01 import OpenBDPage
from taobao.pages.page02 import SearchBDPage
from taobao.pages.page03 import WindowBDPage
from taobao.pages.page04 import TaoBaoPage
from taobao.pages.page05 import WindowTBPage
import time

class TaoBaoTest(unittest.TestCase):
    # 执行测试用例的前置条件
    @classmethod
    def setUpClass(cls) -> None:
        cls.driver=webdriver.Firefox()
        cls.driver.maximize_window()
        cls.driver.implicitly_wait(30)
    def test_01(self):
        p1=OpenBDPage(self.driver)
        p1.open_baidu('http://www.baidu.com')
    def test_02(self):
        p2=SearchBDPage(self.driver)
        p2.input_data('淘宝官网')
        p2.click_baidu()
        p2.click_taobao()
    def test_03(self):
        p3=WindowBDPage(self.driver)
        p3.switch_window_taobao(1)
        p3.click_login()
        p3.click_qrcode()
    def test_04(self):
        p4=TaoBaoPage(self.driver)
        p4.input_data('苹果13')
        p4.click_search()
        p4.click_baoyou()
        p4.send_min_price(5000)
        p4.send_max_price(50000)
        time.sleep(2)
        p4.click_confirm()
        p4.click_phone()
    def test_05(self):
        p5=WindowTBPage(self.driver)
        p5.switch_window_phone(2)
        p5.click_color()
        p5.click_store()
        p5.click_shoping()
        p5.click_shopping_car()
    # 执行测试用例的后置条件
    @classmethod
    def tearDownClass(cls) -> None:
        cls.driver.quit()

if __name__ == '__main__':
    unittest.main()

4.生成html测试报告

import unittest
from taobao.testcase.tbtestcase import TaoBaoTest
from po.data.HTMLTestRunner import HTMLTestRunner
class HtmlClass():
    def htmlMethod(self):
        suite = unittest.TestSuite()
        # 创建测试套件
        case_list = ["test_01","test_02","test_03","test_04","test_05"]
        for case in case_list:
            suite.addTest(TaoBaoTest(case))
        with open("../report.html","wb") as f:
            HTMLTestRunner(
                stream=f,
                title="淘宝加入购物车",
                description="测试一期",
                verbosity=2
            ).run(suite)
htmlclass = HtmlClass()
htmlclass.htmlMethod()

5.测试报告展示

6.组织代码

五:PO模式的优点

1:PO提供了一种业务流程与页面元素操作分离的模式,这使得测试代码变得更加清晰
2:页面对象与用例分离,使得我们更好的复用对象
3:可复用的页面方法代码会变得更加优化
4:更加有效的命令方式使得我们更加清晰的知道方法所操作的UI元素

相关文章