selenium webdriver (4) -- page object

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
相關文章
相關標籤/搜索