page object 是一种分层的思想,用户并不关心是如何找到元素的,用户只是进行输入,提交这些操做而已,如何让代码进行合理的分层,使得更加接近用户的行为,而隐藏掉一些定位的细节,更参数化,使得代码复用性更高,提升测试用例的可读性以及用例的可维护性python
当web页面编写测试用例时,须要操做web页面上的元素,然而若是在测试代码中直接操做HTML元素,那么这个代码是很是脆弱的,UI是常常变更的,用page对象封装成一个HTML页面,里面包含定位元素,并封装成接口提供给测试用例进行调用,这样在最终的测试用例中无需在HTML中寻找,只是调用接口而已,一旦变更,测试用例的逻辑是不变的,调用的函数仍是那个,只是那个函数定位的元素变了而已web
不是page_object模式把定位元素和测试方法按照过程式的写下来,而page_object设计过的代码则是把定位元素与测试方法分离,用户关心的是classB,而classA对于用户是黑盒的,但它给classB提供接口app
page并不必定是一个页面,更加合理的解释是经过给“页面”建模,使其对测试方法变得更有意义,如登陆框须要输入用户名和密码和登陆操做ide
non_page_object函数
driver.find_element_by_name("uid") driver.find_element_by_name("password") driver.find_element_by_name("submit").click()
page_object测试
import login_page def test_login(username, password): login_page.SetUsername(username) login_page.SetPassword(password) login_page.Submit()
test_login就是接口提供给测试用例调用的接口,能够更改 username,password进行关键字驱动,页面对象层只关心元素定位的问题,测试用例只关心测试的数据,如username,password经过这样的设计,若是webUI中的登陆locator变了,咱们只须要改动login_page,而对于测试用例则不变,不管UI如何变化,登陆的流程是不会变的,输入用户名,密码,提交,这就是分层ui
下面介绍一个实例来讲明page_object的设计设计
打开网页 http://demo/guru99.com/v4/ 获取网页title, 判断是否在一个登陆页面上 输入用户名 输入密码 登陆 获取网页中的一个登陆成功的元素中的文本,验证是否登陆成功
non_page_object_logincode
#!/usr/bin/env python from selenium import webdriver from selenium.webdriver.support.ui import WebDriverWait driver = webdriver.Firefox() driver.implicitly_wait(10) #open page driver.get("http://demo.guru99.com/v4/") #find check point about login_page homeText = driver.find_element_by_xpath("//div[1]/h2").text #judge client open login_page successful assert homeText == "Guru99 Bank", 'cannot go to login page' #set username driver.find_element_by_name("uid").send_keys("mngr44067") #set password driver.find_element_by_name("password").send_keys("etUtamE") #submit driver.find_element_by_name("btnLogin").click() #get text about valid user info hometext = driver.find_element_by_xpath("//table[1]/tbody/tr[3]/td").text #judge user login successful assert hometext == "Manger Id : mngr44067", "invalid user" #invalid user and pop alert to accept try: driver.switch_to_alert().accept() except: pass #verify go back to home page assert homeText == "Guru99 Bank", "no found" driver.close()
红色标出来的就是检查点,这个代码是很是脆弱的,若是换一个用户名,就要重写,若是webUI变更一下,这个代码就要修改对象
page_object分离webElement,test_case,根据页面进行分离,首先是登陆页面,以后是成功登陆后的页面,分别定义,最后再根据用户思想进行测试用例编写
page_login.py
#!/usr/bin/env python from selenium import webdriver from selenium.webdriver.common.by import By class Guru99Login(object): #Locator user = (By.NAME, "uid") password = (By.NAME,"password") homeText = (By.XPATH,"//div[1]/h2") submit = (By.NAME,"btnLogin") #Action def __init__(self,driver): self.driver = driver def SetUsername(self, name): self.driver.find_element(*self.user).send_keys(name) def SetPassword(self,password): self.driver.find_element(*self.password).send_keys(password) def ClickLogin(self): self.driver.find_element(*self.submit).click() def GetLoginTitle(self): return self.driver.find_element(*self.homeText).text #Interface def TestLogin(self, username, password): self.SetUsername(username) self.SetPassword(password) self.ClickLogin()
该文件最主要的是TestLogin函数,把测试用到的数据参数化,提供给测试用例,而以前的Action是对TestLogin的进一步分层,单位动做
page_home.py
#!/usr/bin/env python from selenium import webdriver from selenium.webdriver.common.by import By class Guru99HomePage(object): HomeText_loc = (By.XPATH,"//table[1]/tbody/tr[3]/td") def __init__(self,driver): self.driver = driver def GetHomePageUserName(self): return self.driver.find_element(*self.HomeText_loc).text
该文件是成登陆成功判断用的,因为在另外一个页面,咱们也把它做为page对象封装起来,它的接口就是GetHomePageUserName()
pom_testcase.py
#!/usr/bin/env python from selenium import webdriver from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.common.by import By import unittest, time, re import page_home import page_login class Test_Login(unittest.TestCase): def setUp(self): self.driver = webdriver.Firefox() self.driver.implicitly_wait(10) self.driver.get("http://demo.guru99.com/v4/") def test_home_page_appear(self): objLogin = page_login.Guru99Login(self.driver) loginTitle = objLogin.GetLoginTitle() assert loginTitle == "Guru99 Bank", "title is wrong" objLogin.TestLogin("mngr44067","etUtamE") objHomePage = page_home.Guru99HomePage(self.driver) assert objHomePage.GetHomePageUserName() == "Manger Id : mngr44067", "invalid user" def tearDown(self): self.driver.close() if __name__ == '__main__': unittest.main()
测试用例用unittest
测试方法 test_home_page_appear() 判断title 登陆 判断登陆成功
不管UI如何变,该测试用例无需修改,只须要修改page_login, page_home就好了,代码可用性很高,只须要改用户名,密码就能进行测试
参考:
www.guru99.com <selenium2 自动化测度实战> selenium guide