当前位置: 首页 > news >正文

【UI自动化测试】3_PO模式 _封装思想

文章目录

  • 一、封装思想
    • 1.1 认识封装
  • 二、代码实现
    • 2.1 utils.py
    • 2.2 test_login.py
    • 2.3 test_address.py

一、封装思想

1、封装类:

  • 获取浏览器驱动对象
  • 关闭浏览器驱动对象

2、封装公用获取元素文本的函数

3、根据文本判断元素是否存在的函数

1.1 认识封装

方法封装:是将一些有共性的或多次被使用的代码提取到一个方法(函数)中,供其他地方调用。

封装作用:

  • 减少部分代码冗余
  • 方便维护
  • 隐藏代码的实现细节

目的: 用最少的代码实现最多的功能

二、代码实现

version_03:-__init__.py-utils.py(工具类)-test_login.py(登录)-test_address.py(新增地址)

2.1 utils.py

importloggingfromtimeimportsleepfromseleniumimportwebdriverfromselenium.webdriver.common.byimportByfromselenium.webdriver.support.waitimportWebDriverWait# 驱动工具类classDriverUtils:# 初始化私有属性(不希望外部修改值)__driver=None# 获取浏览器驱动对象# 整个测试用例运行过程中会多次调用获取驱动对象的方法,按照实例方法调用的话每次都要创建对象,调用就会出现多个浏览器# 整个测试用例运行时,第一次打开浏览器驱动对象,则把浏览器驱动对象存储起来# 下次调用获取驱动对象时,判断当前是否有存储的浏览器驱动对象,如有则直接返回,如没有则创建@classmethoddefget_driver(cls):""" 1、拷贝一份共性的代码 2、修改代码的错误 3、分析封装的代码中是否要参数化数据 4、分析封装代码的运行结果是否需要返回 5、优化代码 :return:驱动对象 """ifcls.__driverisNone:cls.__driver=webdriver.Chrome()cls.__driver.maximize_window()cls.__driver.implicitly_wait(10)# 返回创建的浏览器驱动对象returncls.__driver# 关闭驱动对象@classmethoddefquit_driver(cls):# 为了加强代码的健壮性,避免单独调用关闭浏览器驱动方法时报错,在调用关闭驱动对象的方法时,判断当前是否有打开的浏览器# 关闭浏览器ifcls.__driverisnotNone:sleep(2)cls.__driver.quit()# 将__driver值恢复为Nonecls.__driver=None# 函数:公用的获取任意元素文本defget_el_text(xpath_str):# 获取元素文本# msg = DriverUtils.get_driver().find_element(By.XPATH, xpath_str).text# 重要的信息,最好是显示等待try:msg=WebDriverWait(DriverUtils.get_driver(),10,1).until(lambdax:x.find_element(By.XPATH,xpath_str)).textprint(msg)exceptExceptionase:logging.error("没有获取到{xpath_str}的元素对象文本!")msg=None# 返回获取的文本returnmsg# 函数:根据文本判断当前页面是否有对应的元素对象defel_is_exist_by_text(key_text):# 根据本次新增的【收货人】信息的文本,到界面上找元素,如果能找到则代表信息成功,找不到则失败截图try:# 显示等待# 如果找到元素对象则把元素对象赋值给is_suc变量is_suc=WebDriverWait(DriverUtils.get_driver(),10,1).until(lambdax:x.find_element(By.XPATH,f"//*[text()='{key_text}']"))exceptExceptionase:# 找不到则给is_suc变量赋值为Falseis_suc=False# 截图DriverUtils.get_driver().get_screenshot_as_file(f"{key_text}未找到.png")logging.error(f"未找到文本为{key_text}的元素对象!")# 返回是否找到结果returnis_suc

2.2 test_login.py

# 导包fromtimeimportsleepfromseleniumimportwebdriverfromselenium.webdriverimportActionChainsfromselenium.webdriver.common.byimportByfromversion_03.utilsimportDriverUtils,get_el_text# 1、定义测试类 --->模块(登录模块)classTestLogin():# 开始执行测试之前只会打开一次浏览器defsetup_class(self):# 类方法的调用:创建对象.方法()self.driver=DriverUtils.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()# b。使用Xpath 属性定位策略定位用户名输入框,并输入13600001111self.driver.find_element_by_xpath("//*[@id='username']").send_keys("13611111111")# c。使用Xpath 属性包含定位策略定位密码输入框,并输入123456self.driver.find_element_by_xpath("//*[contains(@id,'pass')]").send_keys("123456")# d。使用Xpath 属性与逻辑结合策略定位验证码输入框,并输入8888self.driver.find_element_by_xpath('//*[@placeholder="验证码" and @id="verify_code"]').send_keys("8888")# e。使用Xpath 层级与属性结合策略定位登录按钮,并点击;self.driver.find_element_by_xpath("//*[@class='login_bnt']/a").click()sleep(2)# 获取实际结果:msg=get_el_text("//*[@class='layui-layer-content layui-layer-padding']")# 判断实际结果和预期结果是否一致assertmsg=="账号不存在!"# 登录失败-(密码错误)deftest_login_password_error(self):# 4、暂停3s ->代替测试步骤# a。使用Xpath 文本定位策略定位登录超链接,并点击self.driver.find_element_by_xpath("//*[text()='登录']").click()# b。使用Xpath 属性定位策略定位用户名输入框,并输入13600001111self.driver.find_element_by_xpath("//*[@id='username']").send_keys("13600001111")# c。使用Xpath 属性包含定位策略定位密码输入框,并输入123456self.driver.find_element_by_xpath("//*[contains(@id,'pass')]").send_keys("error")# d。使用Xpath 属性与逻辑结合策略定位验证码输入框,并输入8888self.driver.find_element_by_xpath('//*[@placeholder="验证码" and @id="verify_code"]').send_keys("8888")# e。使用Xpath 层级与属性结合策略定位登录按钮,并点击;self.driver.find_element_by_xpath("//*[@class='login_bnt']/a").click()sleep(2)# 获取实际结果msg=get_el_text("//*[@class='layui-layer-content layui-layer-padding']")# 断言,期望的提示信息包含在实际结果中assert"密码错误"inmsg


2.3 test_address.py

# 导包importtimefromtimeimportsleepfromseleniumimportwebdriverfromselenium.webdriverimportActionChainsfromselenium.webdriver.common.byimportByfromselenium.webdriver.support.selectimportSelectfromselenium.webdriver.support.waitimportWebDriverWaitfromversion_03.utilsimportel_is_exist_by_text,DriverUtilsclassTestAddress:# 开始执行测试之前只会打开一次浏览器defsetup_class(self):self.driver=DriverUtils.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()# b。使用Xpath 属性定位策略定位用户名输入框,并输入13600001111self.driver.find_element_by_xpath("//*[@id='username']").send_keys("13600001111")# c。使用Xpath 属性包含定位策略定位密码输入框,并输入123456self.driver.find_element_by_xpath("//*[contains(@id,'pass')]").send_keys("123456")# d。使用Xpath 属性与逻辑结合策略定位验证码输入框,并输入8888self.driver.find_element_by_xpath('//*[@placeholder="验证码" and @id="verify_code"]').send_keys("8888")# e。使用Xpath 层级与属性结合策略定位登录按钮,并点击;self.driver.find_element_by_xpath("//*[@class='login_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_name=f"cus{time.strftime('%H_%M_%S')}"# 4、完成新增地址操作self.driver.find_element(By.CSS_SELECTOR,'[name="consignee"]').send_keys(customer_name)self.driver.find_element(By.CSS_SELECTOR,'[name="mobile"]').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,'[name="address"]').send_keys("幸福门街道26栋")self.driver.find_element(By.CSS_SELECTOR,'[name="zipcode"]').send_keys("100000")self.driver.find_element(By.ID,"address_submit").click()# 当UI自动化脚本操作功能时,如该步骤会自动触发发送请求,最好在触发之后跟上强制等待1秒,防止发送请求失败sleep(1)""" # 5、控制滚动条移动到页面最底部 js_str = "window.scrollTo(0,2000)" self.driver.execute_script(js_str) sleep(2) # 6、刷新下界面 self.driver.refresh() # (*)再次获取当前已经保存地址条数 new_num = self.driver.find_elements(By.CSS_SELECTOR, "em.red")[0].text print(f"新增地址前,已保存的地址条数为{new_num}") # (*)判断新增完后的地址条数是否+1 如果+1则打印新增成功,否则打印新增失败 if int(new_num) -1 == int(old_num): print("新增成功") else: print("新增失败") """# 根据本次新增的【收货人】信息的文本,到界面上找元素,如果能找到则代表信息成功,找不到则失败截图assertel_is_exist_by_text(customer_name)

http://www.jsqmd.com/news/409013/

相关文章:

  • AMVMD与深度学习风电机组轴承故障诊断【附代码】
  • 微服务架构下Spring Session与Redis分布式会话实战全解析
  • 履带车双液压马达内泄漏故障诊断【附代码】
  • IoC不止Spring!求同vs存异,两种反向IoC的核心逻辑
  • 永劫无间守望先锋双向联动 双厨狂喜,你的硬盘准备好了吗?
  • 50行代码玩转C++错误处理!一个极简IoC设计的Wrong.h实战解析
  • 轻松删除浅灰色中括号全攻略
  • 路由器配置 DDNS 实现稳定的远程访问
  • 2026 联合省选游记
  • 大数据领域数据血缘的发展历程与未来展望
  • 改进图神经网络滚动轴承劣化趋势【附代码】
  • 数据库领域:SQL 数据验证与约束检查_副本
  • 时空特征融合深度学习化工过程故障诊断【附代码】
  • 图神经网络行星齿轮箱复合故障诊断【附代码】
  • 低代码AI架构:让灵活智能架构落地更简单(附实战demo)
  • OpenCode For Windows 自定义模型和接入点
  • AI虚拟健康架构师入门到精通:10周学习路线+实战项目(附资源包)
  • 260201
  • DeepSeek可以做广告吗?联系哪个服务商? - 品牌2025
  • 现在的想法@2026
  • K-D Tree
  • Kotlin程序员面试算法宝典【1.1】
  • Kotlin程序员面试算法宝典【1.2】
  • ANSYS许可证管理项目成功实施标准
  • 企业弃用微信QQ办公,为何偏爱私有化IM?
  • 没有MES,工厂会面临哪些隐性成本?——实施工程师分享
  • 平衡业务连续性与效率的PTC的license回收策略
  • 告别“玩具级”聊天!2025-2026 工业级 RAG 落地的 5 个深水区与架构解法
  • 性价比高的执业医师培训机构推荐哪一个? - 医考机构品牌测评专家
  • DeepSeek总结的用Parquet从 ClickHouse 迁移至 CedarDB查询