Selenium之POM设计模式的一点思考

POM设计模式是自动化测试中的一种常见策略,旨在减少重复代码和提高代码复用。它将不同页面视为独立类,包含页面元素和操作方法。与传统设计相比,POM能降低页面UI变化带来的维护成本,但可能增加类的数量。PO类不应包含验证或断言,应专注于提供页面操作。在具体项目中,选择是否使用POM需考虑页面数量和业务复杂度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

什么是POM设计模式? 随着自动化测试的逐渐发展,页面对象模型变得更加流行用来帮助自动化测试减少重复的代码。页面对象模型page object modle是一种设计模式, 要求我们设计代码结构的时候将应用中的不同页面当作不同的类,类中通常包含页面的element以及页面可以进行的操作方法,比如输入,搜索,滑动等方法。

 

01 POM设计和传统设计的区别

不使用POM设计的自动化测试代码,会将元素和页面的操作方法以及测试方法写在同一个类中,这样的好处是编写的时候比较容易,所见即所得,当前用例需要什么数据就写什么方法获取。

但这样的编写的缺点也比较明显,当不同的用例之间有相同的前置条件的时候,重复的代码会大量的增加,随着业务的复杂和自动化测试用例的增加,会导致测试变的更加的混乱,页面UI和数据和用例之间的耦合严重,一旦UI发生变化,维护的成本也会增加。

使用POM设计的自动化测试代码,将页面以及操作都写在对应的page class 中,可以使代码得到很好的复用。拆分的单元越小也就越容易进行复用,尽量避免形式化,即使使用的POM但是class中仍然是多种操作混在一起编写的方法。比如页面上的输入和搜索这应该写两个方法,一个是输入数据,一个是搜索操作。而不应该在把两个操作写在一个方法中。这样其他用例需要某一个单独操作的时候就要重新写方法。但是POM的设计也会带来需要维护的类数量翻倍的问题。使用POM模式后我们不得不维护更多个类,page class和testcase class。

page class除了一个页面一个外,UI测试中为了更好的复用代码,我们一般会将多个页面共同使用的方法单独出来称为一个base page,其他page class集成base page。

举个例子:

from selenium.webdriver.support.wait import WebDriverWaitfrom selenium.webdriver.support import expected_conditions as ECclass BasePage(object):
    def __init__(self, driver):
        self.driver = driver

    def find_element(self, *loc):
        WebDriverWait(self.driver, 1, 5).until(EC.visibility_of(self.driver.find_element(*loc)))
        return self.driver.find_element(*loc)

    def type_text(self, text, *loc):
        self.find_element(*loc).send_keys(text)

    def click(self, *loc):
        self.find_element(*loc).click()

02 PO 类的设计

PO 类就是包含了页面元素和操作方法的类,实际编写的过程中值得注意的是:

1.除了验证页面元素是否被正确地加载在页面对象外。页面对象不应该存在其他的验证或断言。断言是测试的一部分,应该出现在测试的代码中,而不是页面对象。

2.一个页面对象不一定需要代表一个页面本身的所有部分。用于页面对象的相同原则可用于创建 "页面组件对象",它代表页面的离散块,并可包含在页面对象中。这些组件对象可以提供对这些离散块内的元素的引用,以及利用它们所提供的功能的方法。甚至可以将组件对象嵌套在其他组件对象中,以获得更复杂的页面。

3.PageObjects 应该尽可能少的暴露底层的 WebDriver 实例,所以 PageObject 上的方法应该返回其他 PageObjects。

举个例子:

比如我们要进行一个搜索操作,在首页输入信息后点击搜索会进入搜索页面,最后断言搜索结果是不是和预期一致。

这样我们得到了两个页面和一个搜索方法,一个输入方法。首页是 MainPage,搜索页是 SearchPage,我们在首页初始化了 driver,在点击搜索跳转后会进入搜索页,这时候我们可以并传递一个 driver 过去 return SearchPage(self.driver)。这样我们就不需要在搜索页面重新引入 webdriver 重新实例化 driver 了。

下面是 PO 类实现的例子:

class UserRegisterPage(BasePage):
    username_input = (By.NAME, 'username')
    email_input = (By.NAME, 'email')
    pwd_input = (By.NAME, 'pwd')
    register_btn = (By.CLASS_NAME, 'btn')def __init__(self, driver):
    BasePage.__init__(self, driver)def goto_register_page(self):
    self.driver.get("http://localhost:8080/jpress/user/register")
    self.driver.maximize_window()def input_username(self, username):
    self.clear(*self.username_input)
    self.type_text(username, *self.username_input)def input_pwd(self, pwd):
    self.clear(*self.pwd_input)
    self.type_text(pwd, *self.pwd_input)def click_register_btn(self):
    self.click(*self.register_btn)

使用 POM 设计的用例和不使用 POM 设计的用例对比

使用前:

def test_register_code_error(self):
    username = 'test001'
    email = 'test001@qq.com'
    pwd = '123456'
    captcha = '666'
    expected = '验证码不正确'

    self.driver.find_element_by_name('username').send_keys(username)
    self.driver.find_element_by_name('email').send_keys(email)
    self.driver.find_element_by_name('pwd').send_keys(pwd)
    self.driver.find_element_by_name('captcha').send_keys(captcha)
    self.driver.find_element_by_class_name('btn').click()
    WebDriverWait(self.driver, 5).until(EC.alert_is_present())
    alert = self.driver.switch_to.alert
    assert alert.text == expected
    alert.accept()

使用后:

def test_register(self, username, email, pwd, captcha, expected):
    self.registerPage.input_username(username)
    self.registerPage.input_email(email)

    self.registerPage.input_pwd(pwd)
    self.registerPage.input_confirmPwd(confirm_pwd)
    self.registerPage.input_captcha(captcha)
    self.registerPage.click_register_btn()

    WebDriverWait(self.driver, 5).until(EC.alert_is_present())
    alert = self.driver.switch_to.alert
    assert alert.text == expected
    alert.accept()

我们会发现使用POM设计模式的用例封装性更高,页面提供的功能和页面元素都被封装在对应的方法内。但是除了这个用例所在的类外,我们还多维护了一个PO类才实现这个用例。而未使用POM设计模式的用例就比较简单直观。

具体项目中到底怎么取舍这两种不同的设计模式也是仁者见仁、智者见智的。

我认为如果一个项目中页面数量不多且业务逻辑比较复杂,这时候需要使用 POM来松耦合,减少重复代码的同时增加代码的可读性,更能胜任复杂的业务逻辑测试。而一个项目页面数量多且业务不复杂,那也没有非要使用POM模式的必要性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值