Web自动化测试(5)-POM

POM设计模式

1、简介

POM(Page Object Model)设计模式又被称为页面对象模型,其核心思想是将web项目的每个页面当做一个对象,通过分层实现管理架构的优化,提高代码的复用性、可读性、可扩展性以及可维护性。POM设计模式主要分为Base层、PageObject层、TestCase层以及TestData层。

名称功能
Base层页面基础层,处理每个web页面对象的共性,或者说是相同的操作
PageObject层不同的web页面定义不同的页面类,用于处理不同页面的差异性
TestCase层用例层,主要包含页面测试的操作流程
TestData层数据层,主要存储项目数据,包含配置数据、测试数据等

2、简单示例

关键字驱动中的示例POM设计模式的更改,首先构建basepage代码:

from selenium import webdriver
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
import time
class BasePage:
    def __init__(self, driver):
        self.driver = driver
        time.sleep(1)
        self.driver.implicitly_wait(2)
        #超时时长为10s,由于自动化需要等待网页控件的加载,所以这里设置一个默认的等待超时,时长为10秒
        self.wait = WebDriverWait(self.driver, 10) 
    # 打开浏览器
    def open_browser(self,browser):
        browser = browser.capitalize()
        if browser in ["Chrome","Edge","Firefox"]:
            browser_driver = {"Chrome":"chromedriver","Edge":"MicrosoftWebDriver","Firefox":"geckodriver"}
            ##利用反射的方式获取浏览器驱动
            self.driver = getattr(webdriver,browser)("../%s.exe"%(browser_driver[browser]))
            self.driver.maximize_window() #窗口最大化
            self.driver.implicitly_wait(5)
        else:
            raise ValueError("未检测到支持的浏览器类型")
    # 加载网页
    def load_url(self,url):
        self.driver.get(url)
        self.driver.implicitly_wait(2)
    # 定位元素
    def locate_element(self,loc):
        # 使用*提取元组中的元素
        return self.driver.find_element(*loc)
    # 定位元素列表
    def locate_elements(self,loc):
        # 使用*提取元组中的元素
        self.wait.until(EC.presence_of_element_located(loc))
        return self.driver.find_elements(*loc)
    #输入信息
    def input(self,loc,value):
        self.locate_element(loc).send_keys(value)
        self.driver.implicitly_wait(1)
    #点击操作
    def click(self,loc):
        self.locate_element(loc).click()
        self.driver.implicitly_wait(1)
    #批量点击操作
    def click_elements(self,elements,attribute):
        for element in elements:
            if element.get_attribute(attribute):
                element.click()

接着分别构建主页搜索mainpage.py以及搜索结果点击的代码:

import sys
import time
sys.path.append("..")
from base.basepage import BasePage
from selenium.webdriver.common.by import By
class MainPage(BasePage):
    url = "https://www.baidu.com/"

    def open_page(self, url = url):
        self.load_url(url)
    
    def search_content(self, value):
        self.input((By.ID,"kw"),value)
        time.sleep(1)
        self.click((By.ID,"su"))
        time.sleep(2)
import sys
sys.path.append("..")
from base.basepage import BasePage
from selenium.webdriver.common.by import By
import time
class SearchResults(BasePage):
    def get_results(self,content):
        return self.locate_elements((By.XPATH,"//a[contains(string(), \'%s\')]"%(content)))
    
    def click_results(self, content,attribute):
        self.click_elements(self.get_results(content),attribute)
        time.sleep(5)

最后构建testCase测试代码:

from time import time
import unittest
import sys
sys.path.append("..")
from pageobjects.mainpage import MainPage
from pageobjects.searchresults import SearchResults
from selenium import webdriver
import time
class TestBaidu(unittest.TestCase):
    search_content = "selenium"
    attribute = "href"
    @classmethod
    def setUpClass(self):
        self.driver = webdriver.Edge("../../MicrosoftWebDriver.exe")
        self.driver.maximize_window()
        time.sleep(2)
        self.main_page = MainPage(self.driver)
        self.search_page = SearchResults(self.driver)
    @classmethod
    def tearDownClass(self):
        self.driver.quit()
    def test_01_openpage(self):
        self.main_page.open_page()
    def test_02_search(self):
        self.main_page.search_content(self.search_content)
    def test_03_click_results(self):
        self.search_page.click_results(self.search_content,self.attribute)
        time.sleep(5)


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

3、UnitTest框架测试用例执行顺序

从上述示例中可以看出,测试用例的函数都是以“test_dd_xxxx”的命名格式进行命名,其中“dd”表示手动指定测试用例的执行顺序,通常来说unittest框架进行自动化测试时会对测试用例进行排序,通常情况下排序的结果与字符串排序结果类似,因此如果存在多个测试用例,在不补0的情况下“test_11”会比“test_2”先执行,导致测试用例的执行顺序与预期不符的情况,因此,为了避免此种情况的发生,可以采用补0的方式即将“test_2”改为“test_02”,在这种情况下,“test_02”会先于“test_11”执行,对于测试用例特别多,比如成百上千个,可以考虑修改unittest加载测试用例的排序函数,也可以采取补0的方式。

4、数据驱动

数据驱动主要指通过一组数据或者数据文件对同一组脚本进行循环测试,从而实现数据与脚本的分离,从而提供代码的复用性、扩展性。本文利用ddt扩展库实现数据驱动的自动化测试。ddt的安装比较简单,使用如下代码即可完成安装:

pip install ddt

ddt模块主要包含类的装饰器ddt和两个方法装饰器data,具体如下表所示:

名称功能
ddt.ddt装饰类,继承了TestCase类
ddt.data装饰测试方法,参数是一系列的值
ddt.file_dat装饰测试方法,参数是文件名,文件类型可以是json或者yaml

5、简单示例

对上文中的示例进行改进,主要更改testcases.py,主要修改三处,首先引入依赖项,接着对测试类进行装饰,最后对测试方法进行装饰,此外,为了简化测试,删减了test_03测试用例:

from time import time
import unittest
import sys
sys.path.append("..")
from pageobjects.mainpage import MainPage
from pageobjects.searchresults import SearchResults
from selenium import webdriver
import time
from ddt import ddt,data # 第一处修改,引入ddt依赖库
@ddt # 第二处修改,使用类装饰器
class TestBaidu(unittest.TestCase):
    search_content = "selenium"
    attribute = "href"
    @classmethod
    def setUpClass(self):
        self.driver = webdriver.Edge("../../MicrosoftWebDriver.exe")
        self.driver.maximize_window()
        time.sleep(2)
        self.main_page = MainPage(self.driver)
        self.search_page = SearchResults(self.driver)
    @classmethod
    def tearDownClass(self):
        self.driver.quit()
    def test_01_openpage(self):
        self.main_page.open_page()
    # 第三处修改,装饰测试方法
    @data("selenium","web自动化","python")
    def test_02_search(self,search_content):
        self.main_page.search_content(search_content)


if __name__ == '__main__':
    unittest.main()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

星空下的仰望者

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值