网站开发进度计划表,工业厂房设计,网站建设与管理做什么,时尚网站文章目录一、PO模式介绍1.1 version_03的问题1.2 PO模式1.2.1 PO模式概念1.2.2 PO模式编写步骤二、PO模式代码实现2.1 page2.1.1 login_page.py2.2 script2.2.1 test_login.py2.2.2 test_address.py2.3 utils.py一、PO模式介绍 1.1 version_03的问题 多个测试用例对于同样的场…文章目录一、PO模式介绍1.1 version_03的问题1.2 PO模式1.2.1 PO模式概念1.2.2 PO模式编写步骤二、PO模式代码实现2.1 page2.1.1 login_page.py2.2 script2.2.1 test_login.py2.2.2 test_address.py2.3 utils.py一、PO模式介绍1.1 version_03的问题多个测试用例对于同样的场景可能重复多次例如登录元素的定位代码在新增地址、下单、收藏商品、取消订单…都会出现。如前端人员稍微修改一下页面的HTML信息所有该元素的定位全部都得找出来进行修改。UI自动化代码对于页面的依赖非常严重。## 1.3 引入PO模式的好处引入PO模式前-存在大量冗余代码-业务流程不清晰-后期维护成本大 引入PO模式后-减少冗余代码-业务代码和测试代码被分开 降低耦合性-维护成本低1.2 PO模式PO是Page Object的缩写 PO模式是自动化测试项目开发实践的最佳设计模式之一。核心思想通过对界面元素的封装减少冗余代码 同时在后期维护中 若元素定位发生变化 只需要调整页面元素封装的代码 提高测试用例的可维护性、 可读性。PO能解决什么问题?-1、代码复用性-2、便于维护(脚本层与业务分离)--如果元素信息发生变化了也不用去修改脚本。1.2.1 PO模式概念将页面当做一个对象将页面上的元素信息当做对象的属性将页面上的操作步骤当做对象的方法。在完成测试用例组织时只需要调用测试用例在各页面中所执行的业务方法即可完成。1.2.2 PO模式编写步骤1、定义页面元素实例属性根据测试用例场景定义好所要用到的元素的实例属性2、定义页面业务实例方法一个页面可能存在多个业务方法如登陆页面登陆、找回密码等3、抽取定位信息到实例属性将元素定位的信息抽离到实例属性中进行统一管理,方便维护二、PO模式代码实现version_04 (包) ①page - __init__.py - login_page.py ②script - __init__.py - test_address.py - test_login.py - ③utils.py2.1 page2.1.1 login_page.py1、创建代表指定页面的py文件。2、定义页面对象3、定义该页面中所用的元素实例属性)4、定义该页面中业务方法实例方法) – 测试用例在该页面中所执行的操作步骤fromselenium.webdriver.common.byimportByfromversion_04.utilsimportDriverUtils# 定义页面对象classLoginPage:# 定义页面实例属性页面上的元素信息 --存储对应元素的定位信息定位方式、该定位方式所需要对应的值def__init__(self):# 驱动对象self.driverDriverUtils.get_driver()# 用户名输入框self.username(By.ID,username)# 密码输入框self.password(By.ID,password)# 验证码输入框self.verify_code(By.ID,verify_code)# 登录按钮self.login_btn(By.XPATH,//*[classlogin_bnt]/a)# 定义哪些元素:测试工程师所要测试的内容用到该页面哪些元素就定义哪些元素# 定义页面业务方法组装该页面上的一些操作形成操作步骤deftp_login(self,user,pwd,code): :param user: 用户名 :param pwd: 密码 :param code: 验证码 :return: # 方法2:元祖拆包# ①清空用户名输入框(为了加强测试代码的健壮性)self.driver.find_element(*self.username).clear()# 输入用户名self.driver.find_element(*self.username).send_keys(user)# 清空密码输入框self.driver.find_element(*self.password).clear()# 输入密码self.driver.find_element(*self.password).send_keys(pwd)# 清空验证码输入框self.driver.find_element(*self.verify_code).clear()# 输入验证码self.driver.find_element(*self.verify_code).send_keys(code)# 点击登录self.driver.find_element(*self.login_btn).click()原始方法 # 输入用户名 self.driver.find_element(By.XPATH,//*[idusername]).send_keys(user) # 输入密码 self.driver.find_element(By.XPATH,//*[contains(id,pass)]).send_keys(pwd) # 输入验证码 self.driver.find_element(By.XPATH,//*[placeholder验证码 and idverify_code]).send_keys(code) # 点击登录 self.driver.find_element(By.XPATH,//*[classlogin_bnt]/a).click() 方法1 # 输入用户名 self.driver.find_element(self.username[0], self.username[1]).send_keys(user) # 输入密码 self.driver.find_element(self.password[0], self.password[1]).send_keys(pwd) # 输入验证码 self.driver.find_element(self.verify_code[0], self.verify_code[1]).send_keys(code) # 点击登录 self.driver.find_element(self.login_btn[0], self.login_btn[1]).click() 2.2 script2.2.1 test_login.py# 导包fromtimeimportsleepfromseleniumimportwebdriverfromselenium.webdriverimportActionChainsfromselenium.webdriver.common.byimportByfromversion_04.utilsimportDriverUtils,get_el_textfromversion_04.page.login_pageimportLoginPage# 1、定义测试类 ---模块登录模块classTestLogin():# 开始执行测试之前只会打开一次浏览器defsetup_class(self):# 类方法的调用创建对象.方法()self.driverDriverUtils.get_driver()# 所有的测试用例都运行完毕才会关闭浏览器defteardown_class(self):DriverUtils.quit_driver()# 每个测试方法的起点一致那么证明每个测试方法运行之前都会回到首页defsetup(self):self.driver.get(https://hmshop-test.itheima.net/)# 2、定义测试方法 --- 标题# 登录失败-账户不存在deftest_login_account_not_exist(self):# 4、暂停3s -代替测试步骤# a。使用Xpath 文本定位策略定位登录超链接并点击self.driver.find_element_by_xpath(//*[text()登录]).click()# 通过调用LoginPage登录页面的登录方法完成登录操作LoginPage().tp_login(13611111111,123456,8888) # b。使用Xpath 属性定位策略定位用户名输入框并输入13600001111 self.driver.find_element_by_xpath(//*[idusername]).send_keys(13611111111) # c。使用Xpath 属性包含定位策略定位密码输入框并输入123456 self.driver.find_element_by_xpath(//*[contains(id,pass)]).send_keys(123456) # d。使用Xpath 属性与逻辑结合策略定位验证码输入框并输入8888 self.driver.find_element_by_xpath(//*[placeholder验证码 and idverify_code]).send_keys(8888) # e。使用Xpath 层级与属性结合策略定位登录按钮并点击 self.driver.find_element_by_xpath(//*[classlogin_bnt]/a).click() sleep(2)# 获取实际结果msgget_el_text(//*[classlayui-layer-content layui-layer-padding])# 判断实际结果和预期结果是否一致assertmsg账号不存在!# 登录失败-密码错误deftest_login_password_error(self):# 4、暂停3s -代替测试步骤# a。使用Xpath 文本定位策略定位登录超链接并点击self.driver.find_element_by_xpath(//*[text()登录]).click()# 通过调用LoginPage登录页面的登录方法完成登录操作LoginPage().tp_login(13600001111,error,8888) # b。使用Xpath 属性定位策略定位用户名输入框并输入13600001111 self.driver.find_element_by_xpath(//*[idusername]).send_keys(13600001111) # c。使用Xpath 属性包含定位策略定位密码输入框并输入123456 self.driver.find_element_by_xpath(//*[contains(id,pass)]).send_keys(error) # d。使用Xpath 属性与逻辑结合策略定位验证码输入框并输入8888 self.driver.find_element_by_xpath(//*[placeholder验证码 and idverify_code]).send_keys(8888) # e。使用Xpath 层级与属性结合策略定位登录按钮并点击 self.driver.find_element_by_xpath(//*[classlogin_bnt]/a).click() sleep(2)# 获取实际结果msgget_el_text(//*[classlayui-layer-content layui-layer-padding])# 断言期望的提示信息包含在实际结果中assert密码错误inmsg2.2.2 test_address.py# 导包importtimefromtimeimportsleepfromseleniumimportwebdriverfromselenium.webdriverimportActionChainsfromselenium.webdriver.common.byimportByfromselenium.webdriver.support.selectimportSelectfromselenium.webdriver.support.waitimportWebDriverWaitfromversion_04.utilsimportel_is_exist_by_text,DriverUtilsfromversion_04.page.login_pageimportLoginPageclassTestAddress:# 开始执行测试之前只会打开一次浏览器defsetup_class(self):self.driverDriverUtils.get_driver()self.driver.get(https://hmshop-test.itheima.net/)# 所有的测试用例都运行完毕才会关闭浏览器defteardown_class(self):DriverUtils.quit_driver()deftest_01_login_suc(self):# a。使用Xpath 文本定位策略定位登录超链接并点击self.driver.find_element_by_xpath(//*[text()登录]).click()# 通过调用LoginPage登录页面的登录方法完成登录操作LoginPage().tp_login(13600001111,123456,8888) # b。使用Xpath 属性定位策略定位用户名输入框并输入13600001111 self.driver.find_element_by_xpath(//*[idusername]).send_keys(13600001111) # c。使用Xpath 属性包含定位策略定位密码输入框并输入123456 self.driver.find_element_by_xpath(//*[contains(id,pass)]).send_keys(123456) # d。使用Xpath 属性与逻辑结合策略定位验证码输入框并输入8888 self.driver.find_element_by_xpath(//*[placeholder验证码 and idverify_code]).send_keys(8888) # e。使用Xpath 层级与属性结合策略定位登录按钮并点击 self.driver.find_element_by_xpath(//*[classlogin_bnt]/a).click() sleep(2)deftest_02_add_address(self):# 2、在个人中心页面点击【账户设置】下【收货地址】ActionChains(self.driver).move_to_element(self.driver.find_element(By.XPATH,//*[text()账户设置])).perform()self.driver.find_element(By.XPATH,//*[text()收货地址]).click() # *获取当前已经保存地址条数 old_num self.driver.find_elements(By.CSS_SELECTOR, em.red)[0].text print(f新增地址前已保存的地址条数为{old_num}) # 3、点击【新增地址】收货人信息 cus{当前时间}self.driver.find_element(By.XPATH,//*[text()增加新地址]).click()customer_namefcus{time.strftime(%H_%M_%S)}# 4、完成新增地址操作self.driver.find_element(By.CSS_SELECTOR,[nameconsignee]).send_keys(customer_name)self.driver.find_element(By.CSS_SELECTOR,[namemobile]).send_keys(13600001112)Select(self.driver.find_element(By.ID,province)).select_by_value(1)# value属性值为1代表北京Select(self.driver.find_element(By.ID,city)).select_by_value(2)# 市辖区2Select(self.driver.find_element(By.ID,district)).select_by_value(39)# 朝阳区39Select(self.driver.find_element(By.ID,twon)).select_by_value(40)# 建外街道40self.driver.find_element(By.CSS_SELECTOR,[nameaddress]).send_keys(幸福门街道26栋)self.driver.find_element(By.CSS_SELECTOR,[namezipcode]).send_keys(100000)self.driver.find_element(By.ID,address_submit).click()# 当UI自动化脚本操作功能时如该步骤会自动触发发送请求最好在触发之后跟上强制等待1秒防止发送请求失败sleep(1)# 根据本次新增的【收货人】信息的文本到界面上找元素如果能找到则代表信息成功找不到则失败截图assertel_is_exist_by_text(customer_name)2.3 utils.pyimportloggingfromtimeimportsleepfromseleniumimportwebdriverfromselenium.webdriver.common.byimportByfromselenium.webdriver.support.waitimportWebDriverWait# 驱动工具类classDriverUtils:# 初始化私有属性(不希望外部修改值)__driverNone# 获取浏览器驱动对象# 整个测试用例运行过程中会多次调用获取驱动对象的方法按照实例方法调用的话每次都要创建对象调用就会出现多个浏览器# 整个测试用例运行时第一次打开浏览器驱动对象则把浏览器驱动对象存储起来# 下次调用获取驱动对象时判断当前是否有存储的浏览器驱动对象如有则直接返回如没有则创建classmethoddefget_driver(cls): 1、拷贝一份共性的代码 2、修改代码的错误 3、分析封装的代码中是否要参数化数据 4、分析封装代码的运行结果是否需要返回 5、优化代码 :return:驱动对象 ifcls.__driverisNone:cls.__driverwebdriver.Chrome()cls.__driver.maximize_window()cls.__driver.implicitly_wait(10)# 返回创建的浏览器驱动对象returncls.__driver# 关闭驱动对象classmethoddefquit_driver(cls):# 为了加强代码的健壮性避免单独调用关闭浏览器驱动方法时报错在调用关闭驱动对象的方法时判断当前是否有打开的浏览器# 关闭浏览器ifcls.__driverisnotNone:sleep(2)cls.__driver.quit()# 将__driver值恢复为Nonecls.__driverNone# 函数公用的获取任意元素文本defget_el_text(xpath_str):# 获取元素文本# msg DriverUtils.get_driver().find_element(By.XPATH, xpath_str).text# 重要的信息最好是显示等待try:msgWebDriverWait(DriverUtils.get_driver(),10,1).until(lambdax:x.find_element(By.XPATH,xpath_str)).textprint(msg)exceptExceptionase:logging.error(没有获取到{xpath_str}的元素对象文本)msgNone# 返回获取的文本returnmsg# 函数根据文本判断当前页面是否有对应的元素对象defel_is_exist_by_text(key_text):# 根据本次新增的【收货人】信息的文本到界面上找元素如果能找到则代表信息成功找不到则失败截图try:# 显示等待# 如果找到元素对象则把元素对象赋值给is_suc变量is_sucWebDriverWait(DriverUtils.get_driver(),10,1).until(lambdax:x.find_element(By.XPATH,f//*[text(){key_text}]))exceptExceptionase:# 找不到则给is_suc变量赋值为Falseis_sucFalse# 截图DriverUtils.get_driver().get_screenshot_as_file(f{key_text}未找到.png)logging.error(f未找到文本为{key_text}的元素对象)# 返回是否找到结果returnis_suc