PO设计模式

PO模式

  • PO是什么?
PO:Page Object(页面对象),将自动化涉及的页面或模块封装成对象。
  • PO能解决什么问题?
1、代码复用性
2、便于维护(脚本层与业务分离)--如果元素信息发生变化了,也不用去修改脚本。
  • PO如何做?

    • Base层
    存放所有页面公共方法
    
    • Page层
    基于页面或模块单独封装当前页面要操作的对象
    
    • Script层
    脚本层+unittest
    
  • 非PO模式代码实现

    import unittest
    from selenium import  webdriver
    from selenium.webdriver.common.by import By
    class TestLogin(unittest.TestCase):
        def setUp(self) -> None:
            self.driver=webdriver.Chrome()
            self.driver.maximize_window()
            self.driver.get("https://hmshop-test.itheima.net/Home/user/login.html")
            self.driver.implicitly_wait(10)
    
        def tearDown(self) -> None:
            sleep(5)
            self.driver.quit()
    
        def test01_login(self):
            #输入用户名
            self.driver.find_element(By.CSS_SELECTOR,"#username").send_keys("16612345678")
            #输入密码
            self.driver.find_element(By.CSS_SELECTOR, "#password").send_keys("123456")
            #输入验证密码
            self.driver.find_element(By.CSS_SELECTOR, "#verify_code").send_keys("8888")
            #点击登录
            self.driver.find_element(By.CSS_SELECTOR, ".J-login-submit").click()
    

PO设计

  • 结构
    • base:存放所有Page页面公共方法
    • page:将页面封装为对象
    • script:测试脚本

案例(登录)

  • base:分析要实现页面公共方法
"""
Base类:存放所有Page页面公共操作方法!
"""
from selenium.webdriver.support.wait import WebDriverWait
class Base:
    def __init__(self, driver):
        self.driver = driver
        # 查找元素
        # 输入方法
        # 点击方法
        # 获取文本值方法	
  • base实现
"""Base类:存放所有Page页面公共操作方法"""
from selenium.webdriver.support.wait import WebDriverWait

class Base:
    def __init__(self,driver):
        self.driver=driver
    #查找方法
    def base_find(self,loc,timeout=10,poll_frequency=0.5):
        #显示等待 ->查找元素 loc=(By.ID,"userA") *loc=loc[0],loc[1]
        return WebDriverWait(self.driver,timeout,poll_frequency).until(lambda  x:x.find_element(loc[0],loc[1]))

    #输入方法
    def base_input(self,loc,value):
        #获取元素
        el =self.base_find(loc)
        #清空操作
        el.clear()
        # 输入内容
        el.send_keys(value)

    #点击方法
    def base_click(self,loc):
        self.base_find(loc).click()

    #获取文本值方法
    def base_get_text(self,loc):
        return self.base_find(loc).text
  • page结构搭建
"""
模块名:page_模块单词
类名:大驼峰将模块移植进来,去掉下划线和数字
方法:自动化测试当前页面要操作哪些元素,就封装哪些元素
"""

class PageLogin:
    #输入用户名
    def __page_username(self):
        pass

    #输入密码
    def __page_pwd(self):
        pass
    #输入验证码
    def __page_verify_code(self):
        pass

    #点击登录按钮
    def __page_click_login_btn(self):
        pass
    #获取昵称
    def page_get_nickname(self):
        pass
    # 组合业务方法 (强调:测试业务成调用此方法,便捷。)
    def page_login(self):
        pass
  • 配置信息整理
# 验证码
verify_code = By.CSS_SELECTOR, "#verify_code"
# 登录按钮
login_btn = By.CSS_SELECTOR, ".J-login-submit"
# 昵称
nick_name = By.CSS_SELECTOR, ".userinfo"
# 提示:nick_name = By.CLASS_NAME, ".userinfo" == (By.CLASS_NAME,".userinfo")
  • page实现
"""
模块名:page_模块单词
类名:大驼峰将模块移植进来,去掉下划线和数字
方法:自动化测试当前页面要操作哪些元素,就封装哪些元素
"""
from selenium.webdriver.common.by import By
from base.base import Base

#用户名
username = (By.CSS_SELECTOR,"#username")
#密码
pwd = By.CSS_SELECTOR,"#password"
#验证码
verify_code = By.CSS_SELECTOR,"#verify_code"
#登录按钮
login_btn=By.CSS_SELECTOR,".J-login-submit"
#昵称
nick_name=By.CSS_SELECTOR,".userinfo"

class PageLogin(Base):
    #输入用户名
    def __page_username(self,value):
        self.base_input(username,value)

    #输入密码
    def __page_pwd(self, value):
        self.base_input(pwd, value)
    #输入验证码
    def __page_verify_code(self, value):
        self.base_input(verify_code, value)

    #点击登录按钮
    def __page_click_login_btn(self):
        self.base_click(login_btn)
    #获取昵称
    def page_get_nickname(self):
        return self.base_get_text(nick_name)
    # 组合业务方法 (强调:测试业务成调用此方法,便捷。)
    def page_login(self,phone,password,code):
        self.__page_username(phone)
        self.__page_pwd(password)
        self.__page_verify_code(code)
        self.__page_click_login_btn()
  • script实现
import unittest
from selenium import webdriver
from page.page_login import PageLogin

class TestLogin(unittest.TestCase):
    def setUp(self) -> None:
        self.driver=webdriver.Chrome()
        self.driver.maximize_window()
        self.driver.get("https://hmshop-test.itheima.net/Home/user/login.html")
        self.login =PageLogin(self.driver)

    def tearDown(self) -> None:
        self.driver.quit()
    def test01_login(self,phone="13012345678 ",password="123456",code="8888"):
        #调用登录业务
        self.login.page_login(phone,password,code)
        #断言
        nickname=self.login.page_get_nickname()
        print("nickname",nickname)

数据驱动(parameterized)

理论回顾

  • 什么是数据驱动?
以测试数据驱动用例执行(测试数据和代码分离)
  • 为什么要数据驱动?
便于维护(维护的焦点从代码转到测试数据)
  • 数据如何操作?
1、编写数据存储文件
2、编程读取数据工具
3、使用参数化引用

实际操作

  • 步骤1、编写数据存储文件
口诀:
	1、新建json文件,在文件中编写一个{}
	2、有几个模块,写几个key,值为列表
	3、列表中参数化数据有几组,就写几个{}
	3、每个{}中组成->说明+参数数据+预期结果
  • login.json
{
"login": [
  {
    "desc": "登录成功",
    "phone": "13012345678",
    "password": "123456",
    "code": "8888",
    "expect_text": "13012345678"
  }
]
}
  • 步骤2、读取工具封装(util.py)
import json
import os

#读取json工具
def read_json(filename,key):
    filepath = os.path.dirname(__file__)+os.sep+"data"+os.sep+filename
    arr=[]
    with open(filepath,"r",encoding="utf-8") as f:
        for data in  json.load(f).get(key):
            arr.append(tuple(data.values())[1:])
        return arr
if __name__ == '__main__':
    print(read_json("login.json","login"))
  • 步骤3、参数化引用
import unittest
from time import sleep
from selenium import webdriver
from page.page_login import PageLogin
from parameterized import parameterized
from util import read_json

class TestLogin(unittest.TestCase):
    def setUp(self) -> None:
        self.driver=webdriver.Chrome()
        self.driver.maximize_window()
        self.driver.get("https://hmshop-test.itheima.net/Home/user/login.html")
        self.login =PageLogin(self.driver)

    def tearDown(self) -> None:
        sleep(3)
        self.driver.quit()
    @parameterized.expand(read_json("login.json","login"))
    def test01_login(self,phone,password,code,expect_text):
        try:

            #调用登录业务
            self.login.page_login(phone,password,code)
            #断言
            nickname=self.login.page_get_nickname()
            print("nickname",nickname,expect_text)
        except Exception as e:
            print("错误!",e)
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值