赞
踩
PO模式是一种自动化测试设计模式,将页面定位和业务操作分开,也就是把对象定位和测试脚本分开,从而提供可维护性。
PO是Page Object(页面对象)的缩写,PO模式是自动化测试项目开发实践的最佳设计模式之一,核心思想是通过对界面元素的封装减少冗余代码,主要体现在对界面交互细节的封装,也就是在实际测试中只关注业务流程;同时在后期维护中,若元素定位发生变化, 只需要调整页面元素封装的代码,提高测试用例的可维护性、可读性。
PO模式可以把一个页面分为三层,对象库层、操作层、业务层。
Base(基类):封装page 页面一些公共的方法,如初始化方法、查找元素方法、点击元素方法、输入方法、获取文本方法、截图方法等
注意:
page(页面对象):封装对元素的操作,一个页面封装成一个对象;
scripts(业务层):将一个或多个操作组合起来完成一个业务功能。比如登录:需要输入帐号、密码、点击登录三个操作。
为更好的理解PO模式,下面采用版本迭代的方式来学习,便于对不同版本的优缺点进行对比和理解。
对TPshop项目的登录模块进行自动化测试,以账号不存在及密码错误为例作为测试用例。
""" 登录功能-账号不存在 """ from selenium import webdriver # 创建浏览器驱动对象,并完成初始化操作 driver = webdriver.Firefox() driver.maximize_window() driver.implicitly_wait(10) driver.get("http://localhost") # 点击首页的‘登录’链接,进入登录页面 # 输入用户名 driver.find_element_by_id("username").send_keys("11234567843") # 输入密码 driver.find_element_by_name("password").send_keys("23615115") # 点击登录按钮 driver.find_element_by_name("sbtbutton").click() # 获取提示信息 msg = driver.find_element_by_class_name(".layui-layer-padding").text print("msg=", msg) expect_result ="账号不存在!" try: # 断言 assert expect_result==msg print("result:",result) except AssertionError: # 截图 driver.get_screenshot_as_file("./{}.png".format(time.strftime("%Y_%m_%d_%H_%M_%S"))) print("result:",result) raise # 关闭驱动对象 driver.quit()
"""
登录功能-密码错误 略
"""
# -*-coding:utf-8 -*- # Auothor:yue_luo import time import unittest from time import sleep from selenium import webdriver class TestLogin(unittest.TestCase): """ 对登录模块的功能进行测试 """ driver = None @classmethod def setUpClass(cls): cls.driver = webdriver.Chrome() cls.driver.maximize_window() cls.driver.implicitly_wait(10) cls.driver.get("http://www.tpshop.com") cls.driver.find_element_by_link_text("登录").click() @classmethod def tearDownClass(cls): cls.driver.quit() # 账号不存在 def test_login_username_is_error(self): # 输入用户名 username =self.driver.find_element_by_id("username") username.clear() username.send_keys("13099999999") # 输入密码 password=self.driver.find_element_by_id("password") password.clear() password.send_keys("123456") # 输入验证码 verify_code = self.driver.find_element_by_id("verify_code") verify_code.clear() verify_code.send_keys("8888") # 点击‘登录’ self.driver.find_element_by_name("sbtbutton").click() # 断言提示信息 msg = self.driver.find_element_by_class_name("layui-layer-content").text print("msg=", msg) try: self.assertIn("账号不存在!", msg) sleep(3) except AssertionError: self.driver.get_screenshot_as_file("./{}.png".format(time.strftime("%Y_%m_%d_%H_%M_%S"))) raise finally: self.driver.find_element_by_css_selector(".layui-layer-btn0").click() def test_login_password_is_error(self): # 输入用户名 username = self.driver.find_element_by_id("username") username.clear() username.send_keys("17864307785") # 输入密码 password = self.driver.find_element_by_id("password") password.clear() password.send_keys("error") # 输入验证码 verify_code = self.driver.find_element_by_id("verify_code") verify_code.clear() verify_code.send_keys("8888") # 点击‘登录’ self.driver.find_element_by_name("sbtbutton").click() # 断言提示信息 msg = self.driver.find_element_by_class_name("layui-layer-content").text print("msg=", msg) try: self.assertIn("密码错误!", msg) sleep(3) except AssertionError: self.driver.get_screenshot_as_file("./{}.png".format(time.strftime("%Y_%m_%d_%H_%M_%S"))) raise finally: self.driver.find_element_by_css_selector(".layui-layer-btn0").click()
引入UnitTest的好处
方便组织、管理多个测试用例
提供了丰富的断言方法
方便生成测试报告
减少了代码冗余
存在的问题
代码冗余
代码结构图
示例代码
"""base.py""" import time from selenium import webdriver from selenium.webdriver.support.wait import WebDriverWait class Base: # 初始化 def __init__(self,driver): self.driver = driver # 查找元素方法 def base_find_element(self,loc,timeout=30,poll_frequency=0.5): return WebDriverWait(driver=self.driver,timeout=timeout,poll_frequency=poll_frequency).until(lambda x:x.find_element(*loc)) # 点击方法 def base_click(self,loc): self.base_find_element(loc).click() # 输入方法 def base_input(self,loc,value): element = self.base_find_element(loc) element.clear() element.send_keys(value) # 获取文本方法 def base_get_text(self,loc): msg = self.base_find_element(loc).text return msg # 截图 def base_get_image(self,): self.driver.get_screenshot_as_file("./{}.png".format(time.strftime("%Y_%m_%d_%H_%M_%S")))
"""get_driver.py""" # -*-coding:utf-8 -*- # Auothor:yue_luo from selenium import webdriver from v3 import page class GetDriver: driver = None @classmethod def get_driver(cls): if cls.driver == None: cls.driver = webdriver.Chrome() cls.driver.maximize_window() cls.driver.get(page.url) return cls.driver @classmethod def quit_driver(cls): if cls.driver: cls.driver.quit() """置空""" cls.driver = None
"""__init__.py""" # -*-coding:utf-8 -*- # Auothor:yue_luo from selenium.webdriver.common.by import By """以下为服务器域名配置地址""" url ="http://www.tpshop.com" """以下为登录页面配置信息""" # 登录链接 login_link = By.PARTIAL_LINK_TEXT , "登录" # 用户名 login_username = By.ID,"username" # 密码 login_pwd = By.NAME,"password" # 验证码 login_verify_code = By.CSS_SELECTOR,"#verify_code" # 登录按钮 login_btn =By.NAME,"sbtbutton" # 获取异常文本信息 login_err_info = By.CLASS_NAME,"layui-layer-content" # 异常提示框 确定按钮 login_err_btn_ok = By.CSS_SELECTOR,".layui-layer-btn0"
"""page_login.py""" from v3 import page from v3.base.base import Base class PageLogin(Base): # 点击登录链接 def page_click_login_link(self): self.base_click(page.login_link) # 输入用户名 def page_input_username(self,username): self.base_input(page.login_username,username) # 输入密码 def page_input_passwrod(self,pwd): self.base_input(page.login_pwd,pwd) # 输入验证码 def page_input_verify_code(self,code): self.base_input(page.login_verify_code,code) # 点击登录 def page_click_login_btn(self): self.base_click(page.login_btn) # 获取异常提示信息 def page_get_error_info(self): return self.base_get_text(page.login_err_info) # 点击异常信息框 确定 def page_click_error_btn_ok(self): self.base_click(page.login_err_btn_ok) # 截图 def page_get_screenshot(self): self.base_get_image() # 组合业务方法 def page_login(self,username,pwd,code): self.page_input_username(username) self.page_input_passwrod(pwd) self.page_input_verify_code(code) self.page_click_login_btn()
"""test_login.py""" # 导包 import unittest from time import sleep from parameterized import parameterized from v3.base.get_driver import GetDriver from v3.page.page_login import PageLogin # 参数化 def get_data(): return [("13099999999","123456","8888","账号不存在!"), ("17864307785","error","8888","密码错误!")] # 新建测试类并继承 class TestLogin(unittest.TestCase): # setUp @classmethod def setUpClass(cls): # 实例化driver并获取 cls.driver = GetDriver().get_driver() # 实例化 获取登录对象 cls.login =PageLogin(cls.driver) # 点击登录链接 cls.login.page_click_login_link() # tearDown @classmethod def tearDownClass(cls): # 关闭driver浏览器驱动对象 GetDriver().quit_driver() # 登录测试方法 @parameterized.expand(get_data()) def test_login(self,username,pwd,code,expect_result): # 调用登录方法 self.login.page_login(username,pwd,code) # 获取登录提示信息 result = self.login.page_get_error_info() print("result;",result) sleep(1) #断言 try: self.assertIn(result,expect_result) sleep(1) except AssertionError: #截图 self.login.page_get_screenshot() raise finally: # 点击提示框确定按钮 self.login.page_click_error_btn_ok() sleep(1)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。