什么是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模式的必要性。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |