首页 > 编程语言 >Selenium4+Python3系列(十) - Page Object设计模式

Selenium4+Python3系列(十) - Page Object设计模式

时间:2022-12-05 14:39:56浏览次数:33  
标签:username 元素 self Object driver Selenium4 login 设计模式 def

前言

​Page Object(PO)​​​模式,是​​Selenium​​实战中最为流行,并且被自动化测试同学所熟悉和推崇的一种设计模式之一。在设计测试时,把页面元素定位和元素操作方法按照页面抽象出来,分离成一定的对象,然后再进行组织。

相信每个做自动化测试的同学,一定会遇到这样一个非常头疼的问题,那就是页面变化,如果没有使用​​Page Object​​设计模式,这就意味着以前的定位元素方法不能用了,需要重新修改元素定位方式。你需要一个一个从测试脚本中把需要修改的元素定位方式找出来,然后再进行修改。这势必会使脚本维护的成本变高,显然这样的自动化脚本就不会有人愿意使用。

那这时我们使用​​Page Object​​模式就可以解决这个问题了。

PageObject 的优点

  • 减少代码冗余
  • 业务和实现分离
  • 降低代码维护成本

Page Object模式

Page Object 见名知意,就是页面对象,并将页面元素定位方法和元素操作进行分离。

在实际自动化测试实战过程中,我们一般对脚本的实现分为三层:

  • 对象层:用于存放页面元素定位和控件操作。
  • 逻辑层:则是一些封装好的功能用例模块。
  • 业务层:则是我们真正的测试用例的操作部分。

使用 Page Object 类来分离页面元素

对象层

首先我们新建一个类​​login_page​​,登录页面内编写需要操作的元素定位方式和控件操作,具体代码示例如下:

# -*- coding: utf-8 -*-
"""
# @Time : 2022/11/26 22:16
# @Author : longrong.lang
# @FileName: login_page.py
# @Software: PyCharm
# @Motto:ABC(Always Be Coding)
"""
import time

from selenium.webdriver.common.by import By


class LoginPage:
"""
封装元素定位及控件
"""

def __int__(self, driver):
self.driver = driver

# 打开浏览器
def open(self, url):
self.driver.get(url)

# 用户名元素定位
def user_name(self):
return self.driver.find_element(By.CSS_SELECTOR, "input[type='text']")

# 密码元素定位
def pass_word(self):
return self.driver.find_element(By.CSS_SELECTOR, "input[type='password']")

# 登录元素定位
def login_btn(self):
return self.driver.find_element(By.CSS_SELECTOR, "button[name='submit']")

# 错误提示
def error_msg(self):
return self.driver.find_element(By.ID, "alert")

# 输入用户名
def send_username(self, username):
self.user_name().clear()
self.user_name().send_keys(username)

# 输入密码
def send_password(self, password):
self.pass_word().clear()
self.pass_word().send_keys(password)

# 点击登录
def click_login(self):
self.login_btn().click()

# 获取错误提示
def get_errorMsg(self):
time.sleep(1)
return self.error_msg().text

# 退出浏览器
def quit(self):
self.driver.quit()

这里我只对用户名和密码输入框进行了封装,有兴趣的同学也可以接着进行全部元素操作封装。

操作层

我们再新建一个类​​login_action​​,用于登录逻辑的封装,供业务层调用,具体代码示例如下:

# -*- coding: utf-8 -*-
"""
# @Time : 2022/11/26 22:33
# @Author : longrong.lang
# @FileName: login_action.py
# @Software: PyCharm
# @Motto:ABC(Always Be Coding)
"""
import time

from pageobject.login_page import LoginPage


class LoginAction(LoginPage):

def login(self, username, password, expected):
self.open("http://localhost:8080/login")
self.send_username(username)
self.send_password(password)
self.click_login()
time.sleep(1)
msg = self.get_errorMsg()
assert msg == expected
self.quit()

业务层

最后我们新建一个类​​test_login​​,用于业务层的封装,具体代码示例如下:

# -*- coding: utf-8 -*-
"""
# @Time : 2022/11/26 22:43
# @Author : longrong.lang
# @FileName: test_login.py
# @Software: PyCharm
# @Motto:ABC(Always Be Coding)
"""
from pageobject.login_action import LoginAction
from selenium import webdriver
from webdriver_manager.chrome import ChromeDriverManager


class TestLogin(LoginAction):
def test_login(self):
self.driver = webdriver.Chrome(ChromeDriverManager().install())
self.driver.maximize_window()
self.driver.implicitly_wait(5)
self.login("username", "pwd", "登录失败!")

小结

虽然该实现方法看上去复杂多了,但其中的设计好处是不同层关心不同的问题。页面对象只关心元素的定位,测试用例只关心测试数据。

​login_page​​​类中主要对登录页面上元素进行封装,使其成为具体的操作方法。如对用户名、密码框都封装成方法,然后定义​​login(self, username, password, expected)​​方法将单个元素操作组成一个完整的动作,包含输入用户名、密码并点击登录按钮等。

使用时将​​driver、username、pwd、expected​​作为函数的入参,这样的方法具有很强的可重用性。

最后使用​​test_login()​​​方法进行用户操作行为,现在只关心用哪个浏览器、登录的用户名和密码是什么,至少输入框、按钮是如何定位的,则不关心。即实现了不同层关心不同问题。如果再有定位元素变化,只需​​login_page​​这个类维护即可,显然方便了很多。

优秀不够,你是否无可替代

软件测试交流QQ群:721256703,期待你的加入!!

欢迎关注我的微信公众号:软件测试君

Selenium4+Python3系列(十) -  Page Object设计模式_封装




标签:username,元素,self,Object,driver,Selenium4,login,设计模式,def
From: https://blog.51cto.com/u_15009374/5912037

相关文章

  • Selenium4+Python3系列(九) - 上传文件及滚动条操作
    一、上传文件操作上传文件是每个做自动化测试同学都会遇到,而且可以说是面试必考的问题,标准控件我们一般用​​send_keys()​​​就能完成上传,但是我们的测试网站的上传控件......
  • 设计模式之代理模式学习分享[Darren]
    很高兴又在每晚的这个时候和博友有分享今天的学习成果了,感谢大家一直对Darren的支持,也希望各位博友们能将自己的好文章分享出来,在此Darren只是抛砖,希望大家不要吝啬自己的学......
  • Object o = new Object();
    对象的创建过程:1,申请内存,并初始化;2,构造器初始化;3,o指向对象。 对象在内存中的存储布局:  使用jol工具打印java对象在内存的存储布局:  其中,对象头的组成:对......
  • Day31:Object类常用方法
    Object类1.1Object概述Object类是所有类的超类、根类,基类;任何类直接或间接地继承Object类;所有对象都具备Object的方法;Object作为参数可以接受任何对象,作为返回值可以......
  • 设计模式——初学学习经验
    设计模式各位读者朋友你们好,我是你们的好朋友IT黑铁,在这学期的学习过程中初步认识和学习了设计模式和架构思想。以下内容最全的几个是我当前有点理解的模式,其余内容缺少的......
  • 前端修炼之路-设计模式
    什么是设计模式?在软件开发程中通用的解决方案。目前有23中设计模式设计原则:单一职责原则(SRP)、开放封闭原则(OCP)、最少知识原则(LKP)1、代理模式场景1:花店替人送花//声明......
  • 【CVPR2022】Detecting Camouflaged Object in Frequency Domain
    【CVPR2022】DetectingCamouflagedObjectinFrequencyDomain论文有一个非官方的实现:https://github.com/VisibleShadow/Implementation-of-Detecting-Camouflaged-Obje......
  • 设计模式之状态模式
    概述状态模式用于解决系统中复杂对象的状态转换以及不同状态下行为的封装问题。当系统中某个对象存在多个状态,这些状态之间可以进行转换,而且对象在不同状态下行为不相同时......
  • 责任链,桥接,适配器,单例,命令哪个设计模式你最常用呢
    设计原则一、你都了解哪些设计原则,你对这些设计原则有哪些心得1、单一职责原则4、依赖倒置原则2、开闭原则5、里氏替换原则3、接口隔离原则6、迪米特法则1、单一......
  • [Typescript] 125. Extreme - Object Key Paths
    Getallpossiblepathsthatcouldbecalledby _.get (alodashfunction)togetthevalueofanobjecttypeT1=ObjectKeyPaths<{name:string;age:number......