PO模式全稱Page Object Model ,是一種試用於UI自動化層面的分層設計模型。

page:存放頁面元素的操作步驟
from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.support.wait import WebDriverWait from selenium.webdriver.common.by import By from tools.display_wait import display_wait from page_locator.login.login_page_locator import LoginPageLocator as loc class LoginPage(): '''登錄界面''' def __init__(self, driver): self.driver = driver def login(self, username, pwd, remember_user=False): WebDriverWait(self.driver, 10).until(EC.visibility_of_element_located((loc.zt_protocol))) # # 點擊組團推推廣者規范 self.driver.find_element(*loc.zt_protocol).click() # 輸入用戶名 self.driver.find_element(*loc.input_usernane).send_keys(username) # 輸入密碼 self.driver.find_element(*loc.input_pwd).send_keys(pwd) # 點擊登錄 self.driver.find_element(*loc.click_button).click() def get_error_info(self): '''獲取異常登錄的錯誤提示信息''' xpath = "//div[@class='button']/span" display_wait(self.driver, By.XPATH, xpath) return self.driver.find_element_by_xpath(xpath).text
page_locator:存放定位元素的方式和元素對應的值,以元祖形式存儲
'''存放定位元素的方式和值''' from selenium.webdriver.common.by import By class LoginPageLocator(): # 點擊組團推推廣者規范 zt_protocol = (By.XPATH,'//*[@id="agreement"]/div/div[3]') # 輸入用戶名 input_usernane = (By.CLASS_NAME,'userName') # 輸入密碼 input_pwd = (By.XPATH,'//input[@type="password"]') # 點擊登錄 click_button = (By.XPATH,'//div[@class="button"]')
由此可見:page = 頁面操作步驟+頁面元素
test_data:存放測試數據,正常場景數據和異常場景數據分開存放,分別數據類型是列表和字典
# 正常登錄數據 normal_data = {"username":"1489088761@qq.com","pwd":"mg123456"} # 異常場景數據 exception_data = [ {"username":"148908876@qq.com","pwd":"mg123456","expected":"該郵箱尚未注冊,請先注冊"}, {"username":"1489088761@qq.com","pwd":"mg12345","expected":"用戶名與密碼不匹配,請重新輸入"}, {"username":"1","pwd":"1","expected":"請輸入正確的郵箱號"}, ]
testcase:存放測試用例,testcase=測試頁面+測試數據,測試用例里面只有方法的調用和斷言,體現一種出,高內聚低偶和。
import unittest from selenium import webdriver from page.login.login_page import LoginPage from page.home.home_page import HomePage from test_data.common.common_data import login_url from test_data.login.login_data import normal_data, exception_data from ddt import ddt, data @ddt class TestLogin(unittest.TestCase): def setUp(self): self.driver = webdriver.Chrome() self.driver.maximize_window() self.driver.get(login_url) self.lg = LoginPage(self.driver) def test_login_success(self): '''正常登錄''' try: # 輸入用戶名,密碼,登錄 self.lg.login(normal_data['username'], normal_data['pwd']) # 斷言首頁是否有退出這個元素 self.assertTrue(HomePage(self.driver).isEcist_logout_ele()) except Exception as e: print('出現異常是:{}'.format(e)) @data(*exception_data) def test_error_format_login(self, data): '''異常用例3條:未注冊的郵箱,密碼錯誤,錯誤的郵箱號''' try: self.lg.login(data['username'], data['pwd']) print(data['expected']) self.assertEqual(self.lg.get_error_info(), data['expected'], '測試失敗') print(self.lg.get_error_info()) except Exception as e: print('出現異常是:{}'.format(e)) def tearDown(self): self.driver.quit() if __name__ == '__main__': unittest.main()
tools:里面存放一些公共方法:
如上傳文件的方法:
'''實現非input標簽上傳文件,調用此方法需要打開windows上傳文件的系統窗口再調用''' import win32gui import win32con def upload_file(file_path): ''' :param file_path:上傳文件的路徑 :return: ''' dialog = win32gui.FindWindow("#32770", "打開") comboxex32 = win32gui.FindWindowEx(dialog, 0, "ComboBoxEx32", None) combox = win32gui.FindWindowEx(comboxex32, 0, "ComboBox", None) edit = win32gui.FindWindowEx(combox, 0, "Edit", None) button = win32gui.FindWindowEx(dialog, 0, "Button", "打開(&0)") win32gui.SendMessage(edit, win32con.WM_SETTEXT, None, file_path) win32gui.SendMessage(dialog, win32con.WM_COMMAND, 1, button) upload_file(r'C:\Users\admin\Desktop\Screenshot\mvcSnipaste_2019-12-26_20-59-19.png')
顯示等待的方法:
'''顯示等待,等待元素可見''' from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.support.wait import WebDriverWait from selenium.webdriver.common.by import By def display_wait(driver, location_mthod, value): ''' :param driver: driver對象 :param location_mthod: 定位方式,如:By.XPATH :param value: 對應的元素,如:id = 'TANGRAM__PSP_10__footerULoginBtn' :return: ''' WebDriverWait(driver, 10).until(EC.visibility_of_element_located((location_mthod, value)))
全部詳細文件夾規划如圖:

