Web UI自动化测试之PO篇

06-01 1680阅读

 本文大纲截图:

Web UI自动化测试之PO篇

1、PO模式基本介绍

概念:PO是Page Object的缩写,PO模式是自动化测试项目开发实践的最佳设计模式之一。

作用:通过对界面元素的封装减少冗余代码,同时在后期维护中,若元素定位发生变化, 只需要调整页面元素封装的代码,提高测试用例的可维护性、可读性。

2、PO模式核心思想

PO模式核心思想:方法封装。

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

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

好处:

  • 避免代码冗余

  • 容易维护

  • 隐藏代码实现的细节

    套路:

    • 1)确定方法的存放位置:找位置

    • 2)给方法起个合适名字:起名字

    • 3)放入要封装的代码内容:放代码

    • 4)确认是否需要参数和返回值:确必要

    • 5)调用封装好的方法使用:做调用

      PO模式学习思路:

      采用版本迭代的方式来学习,便于对不同版本的优缺点进行对比和理解。

      案例: 对TPshop项目的登录模块进行自动化测试。登录模块包含了很多测试用例,如:账号不存在、密码错误、验证码错误、登录成功等,从中选取代表性的用例来演示。

      选择的测试用例:

      • 账号不存在

        • 1)点击首页"登录"链接,进入登录页面

        • 2)输入一个不存在的用户名

        • 3)输入密码

        • 4)输入验证码

        • 5)点击登录按钮

        • 6)获取错误提示信息

        • 密码错误

          • 1)点击首页"登录"链接,进入登录页面

          • 2)输入用户名

          • 3)输入一个错误的密码

          • 4)输入验证码

          • 5)点击登录按钮

          • 6)获取错误提示信息

            版本迭代:

            • V1:不使用任何设计模式和单元测试框架

            • V2:使用PyTest管理用例,并删除多余的注释掉的代码

              • 1)按模块新建测试类

              • 2)提取出setup和teardown函数中的方法内容;如:setup:实例化浏览器对象driver,打开网页,最大化浏览器,设置隐式等待;teardown:暂停3秒、关闭/退出浏览器

              • 3)提取出setup_class和teardown_class函数中的方法内容;将共同的步骤:打开首页、点击登录进入登录页面 提取到setup函数中;注释掉两个函数中的“ # 1、点击首页"登录"链接,进入登录页面”代码

              • V3:使用方法封装的思想,对代码进行优化。定义获取驱动对象的工具类,封装“获取弹出框的提示消息”。

              • V4:PO页面元素封装步骤

                • 1)对应页面创建页面 PO 代码文件,命名规则:页面功能_page.py,例如:login_page.py

                • 2)定义三个类:

                • 格式:对象层(XxxPage)、操作层(XxxHandle)、业务层(XxxTask)

                • 3)对象层:init 方法中获取浏览器对象;自定义方法:封装元素定位方法;封装元素定位方法需要添加返回值!

                • 4)操作层:init 方法获取对象层对象,根据类名写对应变量名;自定义方法:封装元素操作方法。

                • 5)业务层:init 方法获取操作层对象,根据类名写对应变量名;自定义方法:封装测试业务逻辑。

                • 6)在测试用例文件中,实例化业务层对象,调用测试业务方法,执行测试

                • V5:将元素的定位方法及特征值封装成属性,能够实现集中管理目标元素的定位方法及特征

                  • 如:利用元素定位方法find_element和By将page页面元素信息集中放在page的__init__文件中。

                  • V6:PO模式深入封装,把共同操作提取封装到父类中,子类直接调用父类的方法

                    • page页面的公共方法:初始化方法、查找元素方法、点击元素方法、输入方法、获取文本方法、截图方法 ......

                    • 封装工具类:get_driver、get_logger、read_txt、read_json ......

                      3、PO模式设计说明

                      模式说明:

                      • 说明:PO模式又可以叫POM,是 UI 自动化测试中一个非常流行的设计模式(代码套路)

                      • 核心:将元素定位、操作、业务逻辑 拆分为三个层面(每个曾铭对应一个单独的类),然后通过调用完成最终的测试执行行为的过程。

                      • 好处:就是有元素变化,只需要维护每一个Page就行了,测试步骤变化,只需要维护TestCase即可

                        设计步骤:

                        • 1)首先抽象封装一个Base类,这个基类拥有一些指向Webdriver实例的属性,然后每一个Page继承基类Base,可以通过driver管理每一个Page中的元素,而且在Page中将这些操作封装为一个一个的方法。

                        • 2)Page类封装页面元素对象,继承Base类,调用Base类中封装的操作元素的方法;并组合业务流程方法供TestCase类调用。

                        • 3)TestCase继承unittest里面的TestCase类,并且依赖page类,进行组织测试步骤的工作。

                          4、PO模式三层结构

                          操作层(基类base):

                          • 操作层:对元素操作方法封装

                          • 命名举例:

                            • 模块名:base.py

                            • 函数名:class Base:

                            • 方法名:def base_find():、def base_click():

                            • page页面一些公共的方法:

                              • 初始化方法

                              • 查找元素方法

                              • 点击元素方法

                              • 输入方法

                              • 获取文本方法

                              • 截图方法

                              • ......

                                对象层(page):

                                • 对象层:对元素定位方法封装

                                • 命名规则:

                                  • 模块名:page+下划线+实际操作模块名称。

                                  • 函数名(类名):使用大驼峰讲模块名称抄进来,有下划线去掉下划线。继承Base类。

                                  • 方法名:根据业务需求每个操作步骤单独封装一个方法(涉及元素,将每个元素操作单独封装一个操作方法)。

                                  • 命名举例:

                                    • 模块名:page_login.py

                                    • 函数名(类名):class PageLogin(Base):

                                    • 方法名:def page_input_username(): 输入用户名

                                    • 注意:一个页面封装成一个对象,并继承 base

                                    • 组合业务方法(组装):根据需求组装以上操作步骤。如:page_login

                                      业务层(scripts):

                                      • 业务层:测试业务逻辑封装,将一个或多个操作组合起来完成一个业务功能。

                                      • 命名规则:

                                        • 模块名:test+数字+下划线+实际操作模块名称;如果测试用例存在先后顺序,则可加上数字。

                                        • 测试业务名称:以大驼峰方法将模块名抄进来,有下划线去掉下划线。

                                        • 方法名:def test_login():

                                        • 命名举例:

                                          • 模块名:test01_login.py

                                          • 测试业务名:class TestLogin():

                                          • 方法名:def test_login():

                                          • 说明:业务层实际就是测试脚本,并且要导包调用page页面封装的方法

                                          • 如登录业务:需要输入账号、密码、点击登录三个操作

                                          • 方法:

                                            • 1)初始化方法 setup(),注:在unittest框架中不能使用 __init__初始化方法。如:实例化页面对象、前置操作(如:打开浏览器等)

                                            • 2)结束方法 teardown()。如:关闭驱动

                                            • 3)测试方法。如:根据要操作的业务来实现

                                            • 步骤:

                                                # 导包
                                                # 新建测试类
                                                # setup
                                                # teardown
                                                # 业务测试方法
                                                 # 调用功能方法(如 登录方法)
                                                 # 获取登录提示信息
                                                 # 断言
                                                  # try 捕获异常
                                                 # 截图

                                              5、PO模式下的项目结构

                                              PO模式下的主要项目文件夹:base、page、scripts(cases)、run、tools、data、image、log、report

                                              base

                                              • base.py

                                                import time
                                                from time import sleep
                                                from selenium.webdriver.support.wait import WebDriverWait
                                                from day11_tpshop import page
                                                from day11_tpshop.base.get_logger import GetLogger
                                                 
                                                # 获取log日志器
                                                log = GetLogger().get_logger()
                                                 
                                                 
                                                class Base:
                                                    def __init__(self, driver):
                                                        log.info("[base:]正在获取初始化driver对象:{}".format(driver))
                                                        self.driver = driver
                                                 
                                                    # 查找元素方法 封装
                                                    def base_find(self, loc, timeout=30, poll=0.5):
                                                        log.info("[base]:正在定位:{}元素,默认定位超时时间为:{}".format(loc, timeout))
                                                        # 使用显式等待 查找元素
                                                        return WebDriverWait(self.driver,
                                                                             timeout=timeout,
                                                                             poll_frequency=poll).until(lambda x: x.find_element(*loc))
                                                 
                                                    # 点击元素方法 封装
                                                    def base_click(self, loc):
                                                        log.info("[base]:正在对:{}元素执行点击事件".format(loc))
                                                        self.base_find(loc).click()
                                                 
                                                    # 输入元素方法 封装
                                                    def base_input(self, loc, value):
                                                        log.info("[base]:正在获取:{}元素".format(loc))
                                                        # 获取元素
                                                        el = self.base_find(loc)
                                                        log.info("[base]:正在对:{}元素执行清空操作".format(loc))
                                                        # 输入前 清空
                                                        el.clear()
                                                        log.info("[base]:正在给{}元素输入内容:{}".format(loc, value))
                                                        # 输入
                                                        el.send_keys(value)
                                                 
                                                    # 获取文本信息方法 封装
                                                    def base_get_text(self, loc):
                                                        log.info("[base]:正在获取{}元素文本值".format(loc))
                                                        return self.base_find(loc).text
                                                 
                                                    # 截图方法 封装
                                                    def base_get_img(self):
                                                        log.info("[base]:断言出错,调用截图")
                                                        self.driver.get_screenshot_as_file("../image/{}.png".format(time.strftime("%Y_%m_%d %H_%M_%S")))
                                                 
                                                    # 判断元素是否存在方法 封装
                                                    def base_elememt_is_exist(self, loc):
                                                        try:
                                                            self.base_find(loc, timeout=2)
                                                            log.info("[base]:{}元素查找成功,存在页面".format(loc))
                                                            return True  # 代表元素存在
                                                        except:
                                                            log.info("[base]:{}元素查找失败,不存在当前页面".format(loc))
                                                            return False  # 代表元素不存在
                                                 
                                                    # 回到首页(购物车、下订单、支付)都需要用到此方法
                                                    def base_index(self):
                                                        # 暂停2秒
                                                        sleep(2)
                                                        log.info("[base]:正在打开首页")
                                                        self.driver.get(page.URL)
                                                 
                                                    # 切到frame表单方法 以元素属性切换
                                                    def base_switch_frame(self, element):
                                                        log.info("[base]:正在切换到frame表单")
                                                        self.driver.switch_to.frame(element)
                                                 
                                                    # 回到默认目录方法
                                                    def base_default_content(self):
                                                        log.info("[base]:正在返回默认目录")
                                                        self.driver.switch_to.default_content()
                                                 
                                                    # 切换窗口方法
                                                    def base_switch_to_window(self, title):
                                                        log.info("正在执行切换title值为:{}窗口".format(title))
                                                        self.base_get_title_handle(title)
                                                        # self.driver.switch_to.window(self.base_get_title_handle(title))
                                                 
                                                    # 获取指定title页面的handle方法
                                                    def base_get_title_handle(self, title):
                                                        # 获取当前页面所有的handles
                                                        handles = self.driver.window_handles
                                                        # 遍历handle
                                                        for handle in handles:
                                                            log.info("正在遍历handles:{}-->{}".format(handle, handles))
                                                            # 切换 handle
                                                            self.driver.switch_to.window(handle)
                                                            log.info("切换:{}窗口".format(handle))
                                                            # 获取当前页面title 并判断 是否等于 指定参数title
                                                            log.info("条件成立!返回当前handle{}".format(handle))
                                                            if self.driver.title == title:
                                                                # 返回 handle
                                                                return handle
                                                • get_driver.py

                                                  from selenium import webdriver
                                                  from day11_tpshop import page
                                                   
                                                   
                                                  class GetDriver:
                                                      driver = None
                                                   
                                                      # 获取 driver
                                                      @classmethod
                                                      def get_driver(cls):
                                                          if cls.driver is None:
                                                              cls.driver = webdriver.Chrome()
                                                              # 最大化浏览器
                                                              cls.driver.maximize_window()
                                                              # 打开 url
                                                              cls.driver.get(page.URL)
                                                          # 返回 driver
                                                          return cls.driver
                                                   
                                                      # 关闭 driver
                                                      @classmethod
                                                      def quit_driver(cls):
                                                          if cls.driver:
                                                              cls.driver.quit()
                                                              # 必须置空操作
                                                              cls.driver = None
                                                   
                                                   
                                                  if __name__ == '__main__':
                                                      GetDriver().quit_driver()
                                                  • get_logger.py

                                                    import logging.handlers
                                                    import time
                                                     
                                                     
                                                    class GetLogger:
                                                        logger = None
                                                     
                                                        # 获取logger
                                                        @classmethod
                                                        def get_logger(cls):
                                                            if cls.logger is None:
                                                                # 获取 logger 日志器 并设置名称为“admin”
                                                                cls.logger = logging.getLogger("admin")
                                                                # 设置日志级别
                                                                cls.logger.setLevel(logging.INFO)
                                                                # 获取 控制台处理器
                                                                sh = logging.StreamHandler()
                                                                # 获取 文件处理器 根据时间分割
                                                                th = logging.handlers.TimedRotatingFileHandler("../log/{}.log".format(time.strftime("%Y_%m_%d %H_%M_%S")),
                                                                when="S",
                                                                interval=1,
                                                                backupCount=3,
                                                                encoding="utf-8")
                                                                # 设置 文件处理器 日志级别
                                                                th.setLevel(logging.ERROR)
                                                                # 获取 格式器
                                                                fmt = "%(asctime)s %(levelname)s [%(name)s] [%(filename)s %(funcName)s %(lineno)d] - %(message)s"
                                                                fm = logging.Formatter(fmt)
                                                                # 将 格式器 添加到 处理器
                                                                sh.setFormatter(fm)
                                                                th.setFormatter(fm)
                                                                # 将 处理器 添加到 日志器
                                                                cls.logger.addHandler(sh)
                                                                cls.logger.addHandler(th)
                                                            # 返回日志器
                                                            return cls.logger
                                                     
                                                     
                                                    if __name__ == '__main__':
                                                        logger = GetLogger.get_logger()
                                                        # 日志器应用
                                                        logger.info("这是info日志信息")
                                                        logger.debug("这是debug日志信息")
                                                        logger.warning("这是warning日志信息")
                                                        logger.error("这是error日志信息")

                                                    page:

                                                    • __init__.py

                                                      from selenium.webdriver.common.by import By
                                                      """ 以下为项目服务器地址 """
                                                      URL = "http://localhost"
                                                       
                                                      """ 以下为登录模块涉及元素 配置信息"""
                                                      # 登录链接
                                                      login_link = By.PARTIAL_LINK_TEXT, "登录"
                                                      # 用户名
                                                      login_username = By.CSS_SELECTOR, "#username"
                                                      # 密码
                                                      login_pwd = By.CSS_SELECTOR, "#password"
                                                      # 验证码
                                                      login_verify_code = By.CSS_SELECTOR, "#verify_code"
                                                      # 登录按钮
                                                      login_btn = By.CSS_SELECTOR, ".J-login-submit"
                                                      # 错误提示信息
                                                      login_err_info = By.CSS_SELECTOR, ".layui-layer-content"
                                                      # 错误提示框 确定按钮
                                                      login_err_ok_btn = By.CSS_SELECTOR, ".layui-layer-btn0"
                                                      # 安全退出 按钮
                                                      login_logout_link = By.PARTIAL_LINK_TEXT, "安全退出"
                                                       
                                                       
                                                      """ 以下数据为购物车配置数据 """
                                                      # 搜索框
                                                      cart_search = By.CSS_SELECTOR, "#q"
                                                      # 搜索按钮
                                                      cart_search_btn = By.CSS_SELECTOR, ".ecsc-search-button"
                                                      # 添加购物车 --> 跳转到详情页面
                                                      cart_add_info = By.CSS_SELECTOR, ".p-btn>a"
                                                      # 添加购物车
                                                      cart_add = By.CSS_SELECTOR, "#join_cart"
                                                      # iframe 表单名称
                                                      cart_frame_name = By.CSS_SELECTOR, "layui-layer-iframe1"
                                                      # id 属性 定义元素
                                                      cart_frame_id = By.CSS_SELECTOR, "#layui-layer-iframe1"
                                                      # 获取添加购物车结果
                                                      cart_add_result = By.CSS_SELECTOR, ".conect-title>span"
                                                      # 关闭提示窗口
                                                      cart_close_window = By.CSS_SELECTOR, ".layui-layer-close"
                                                       
                                                       
                                                      """ 以下数据为订单页面配置数据 """
                                                      # 我的购物车
                                                      order_my_cart = By.CSS_SELECTOR, ".c-n"
                                                      # 全选
                                                      order_all = By.CSS_SELECTOR, ".checkCartAll"
                                                      # 去结算
                                                      order_account = By.CSS_SELECTOR, ".gwc-qjs"
                                                      # 收货人 备用
                                                      order_person = By.CSS_SELECTOR, ".consignee>b"
                                                      # 提交订单
                                                      order_submit = By.CSS_SELECTOR, ".Sub-orders"
                                                      # 获取提交订单结果
                                                      order_submit_result = By.CSS_SELECTOR, ".erhuh>h3"
                                                       
                                                       
                                                      """ 以下数据为支付模块配置数据 """
                                                      # 我的订单
                                                      pay_my_order = By.PARTIAL_LINK_TEXT, "我的订单"
                                                      # 我的订单页面title 注意:此处为变量,不要By
                                                      pay_my_order_title = "我的订单"
                                                      # 立即支付
                                                      pay_now_payment = By.CSS_SELECTOR, ".ps_lj"
                                                      # 支付页面title
                                                      pay_payment_title = "订单支付-开源商城 | B2C商城 |..."
                                                      # 货到付款
                                                      pay_on_delivery = By.CSS_SELECTOR, "[src='/plugins/payment/cod/logo.jpg']"
                                                      # 确认支付
                                                      pay_confirm_payment = By.CSS_SELECTOR, ".button-confirm-payment"
                                                      # 获取支付结果
                                                      pay_payment_result = By.CSS_SELECTOR, ".erhuh>h3"
                                                      • page_cart.py

                                                        # 导包
                                                        from time import sleep
                                                        from day11_tpshop import page
                                                        from day11_tpshop.base.base import Base
                                                        from day11_tpshop.base.get_logger import GetLogger
                                                         
                                                        # 获取log日志
                                                        log = GetLogger().get_logger()
                                                         
                                                         
                                                        class PageCart(Base):
                                                            # 打开首页
                                                            def page_open_index(self):
                                                                # 注意:由于业务问题,必须暂停2秒,否则在登录时,改变url会报错
                                                                sleep(2)
                                                                log.info("[page_cart]:正在打开首页")
                                                                self.base_index()
                                                         
                                                            # 输入搜索内容 小米手机
                                                            def page_input_search(self, value="小米手机"):
                                                                log.info("[page_cart]:正在输入搜索内容:{}".format(value))
                                                                self.base_input(page.cart_search, value)
                                                         
                                                            # 点击搜索按钮
                                                            def page_click_search_btn(self):
                                                                log.info("[page_cart]:正在点击搜索按钮")
                                                                self.base_click(page.cart_search_btn)
                                                         
                                                            # 点击添加购物车 跳转到商品详情页
                                                            def page_click_add_cart_info(self):
                                                                log.info("[page_cart]:正在点击加入购物车按钮,跳转到商品详情页")
                                                                self.base_click(page.cart_add_info)
                                                         
                                                            # 点击加入购物车
                                                            def page_click_add_cart(self):
                                                                log.info("[page_cart]:正在点击加入购物车按钮,弹出frame表单")
                                                                self.base_click(page.cart_add)
                                                         
                                                            # 点击获取添加结果
                                                            def page_get_text(self):
                                                                # # 切换frame表单 以name属性切换 由于电脑配置问题,导致加载比较慢,不建议使用
                                                                # self.switch_to_frame(page.cart_frame_name)
                                                                # 以元素属性切换 推荐
                                                                self.base_switch_frame(self.base_find(page.cart_frame_id))
                                                                # 获取结果并返回
                                                                log.info("[page_cart]:正在返回购物结果信息")
                                                                return self.base_get_text(page.cart_add_result)
                                                         
                                                            # 关闭窗口
                                                            def page_close_window(self):
                                                                # 回到默认目录
                                                                self.base_default_content()
                                                                # 关闭操作
                                                                log.info("[page_cart]:正在关闭表单弹窗")
                                                                self.base_click(page.cart_close_window)
                                                         
                                                            # 组合业务调用方法
                                                            def page_cart(self):
                                                                log.info("[page_cart]:正在执行添加购物车操作")
                                                                self.page_input_search()
                                                                self.page_click_search_btn()
                                                                self.page_click_add_cart_info()
                                                                self.page_click_add_cart()
                                                        • page_login.py

                                                          from day11_tpshop import page
                                                          from day11_tpshop.base.base import Base
                                                          from day11_tpshop.base.get_logger import GetLogger
                                                           
                                                          # 获取log日志器
                                                          log = GetLogger().get_logger()
                                                           
                                                           
                                                          class PageLogin(Base):
                                                              # 点击 登录链接
                                                              def page_click_login_link(self):
                                                                  log.info("[page_login]:执行{}元素点击链接操作".format(page.login_link))
                                                                  self.base_click(page.login_link)
                                                           
                                                              # 输入用户名
                                                              def page_input_username(self, username):
                                                                  log.info("[page_login]:对{}元素 输入用户名{}操作".format(page.login_username, username))
                                                                  self.base_input(page.login_username, username)
                                                           
                                                              # 输入密码
                                                              def page_input_pwd(self, pwd):
                                                                  log.info("[page_login]:对{}元素 输入密码{}操作".format(page.login_pwd, pwd))
                                                                  self.base_input(page.login_pwd, pwd)
                                                           
                                                              # 输入验证码
                                                              def page_input_verify_code(self, verify_code):
                                                                  log.info("[page_login]:对{}元素 输入验证码{}操作".format(page.login_verify_code, verify_code))
                                                                  self.base_input(page.login_verify_code, verify_code)
                                                           
                                                              # 点击 登录
                                                              def page_click_login_btn(self):
                                                                  log.info("[page_login]:执行{}元素点击操作".format(page.login_btn))
                                                                  self.base_click(page.login_btn)
                                                           
                                                              # 获取 错误提示信息
                                                              def page_get_err_info(self):
                                                                  return self.base_get_text(page.login_err_info)
                                                           
                                                              # 点击 错误提示框 确定按钮
                                                              def page_click_error_alert(self):
                                                                  log.info("[page_login]:执行{}元素点击操作".format(page.login_err_ok_btn))
                                                                  self.base_click(page.login_err_ok_btn)
                                                           
                                                              # 判断是否登录成功
                                                              def page_if_login_success(self):
                                                                  # 注意 一定要将找元素的结果返回,True:存在
                                                                  return self.base_elememt_is_exist(page.login_logout_link)
                                                           
                                                              # 点击 安全退出
                                                              def page_click_logout_link(self):
                                                                  self.base_click(page.login_logout_link)
                                                           
                                                              # 判断是否退出成功
                                                              def page_if_logout_success(self):
                                                                  return self.base_elememt_is_exist(page.login_link)
                                                           
                                                              # 组合业务方法 登录业务直接调用
                                                              def page_login(self, username, pwd, verify_code):
                                                                  log.info("[page_login]:正在执行登录操作,用户名:{},密码:{},验证码:{}".format(username, pwd, verify_code))
                                                                  self.page_input_username(username)
                                                                  self.page_input_pwd(pwd)
                                                                  self.page_input_verify_code(verify_code)
                                                                  self.page_click_login_btn()
                                                           
                                                              # 组合登录业务方法 给(购物车模块、订单模块、支付模块)依赖登录使用
                                                              def page_login_success(self, username="13800001111", pwd="123456", verify_code="8888"):
                                                                  # 点击登录链接
                                                                  self.page_click_login_link()
                                                                  log.info("[page_login]:正在执行登录操作,用户名:{},密码:{},验证码:{}".format(username, pwd, verify_code))
                                                                  self.page_input_username(username)
                                                                  self.page_input_pwd(pwd)
                                                                  self.page_input_verify_code(verify_code)
                                                                  self.page_click_login_btn()
                                                          • page_order.py

                                                            from time import sleep
                                                            from day11_tpshop import page
                                                            from day11_tpshop.base.base import Base
                                                             
                                                             
                                                            class PageOrder(Base):
                                                                # 打开首页
                                                                def page_click_index(self):
                                                                    self.base_index()
                                                             
                                                                # 点击 我的购物车
                                                                def page_click_my_cart(self):
                                                                    self.base_click(page.order_my_cart)
                                                             
                                                                # 点击 全选复选框
                                                                def page_click_all_select(self):
                                                                    # 判断 如果没选中 就进行点击操作
                                                                    if not self.base_find(page.order_all).is_selected():
                                                                        self.base_click(page.order_all)
                                                             
                                                                # 点击 去结算
                                                                def page_click_account(self):
                                                                    self.base_click(page.order_account)
                                                             
                                                                # 备用 查找收货人 --> 动态 解决 收货人加载慢的问题(数据异步加载)
                                                                def page_find_person(self):
                                                                    self.base_find(page.order_person)
                                                             
                                                                # 点击 提交订单
                                                                def page_click_submit_order(self):
                                                                    self.base_click(page.order_submit)
                                                             
                                                                # 获取 订单提交结果
                                                                def page_get_submit_result(self):
                                                                    return self.base_get_text(page.order_submit_result)
                                                             
                                                                # 组装订单业务方法
                                                                def page_order(self):
                                                                    self.page_click_my_cart()
                                                                    self.page_click_all_select()
                                                                    self.page_click_account()
                                                                    # 注意:此处有一个坑,默认收货人在页面加载完成后3秒后才出现。
                                                                    # 解决方法一:使用sleep(5)
                                                                    # sleep(5)
                                                                    # 解决方法二:使用显示等待时长机制,查找收货人元素【推荐】
                                                                    # 找到收货人,说明异步加载完成,收货人信息出现,直接可以执行下一步提交订单操作
                                                                    self.page_find_person()
                                                                    self.page_click_submit_order()
                                                            • page_pay.py

                                                              from day11_tpshop import page
                                                              from day11_tpshop.base.base import Base
                                                               
                                                               
                                                              class PagePay(Base):
                                                                  # 点击 我的订单链接
                                                                  def page_click_my_order_link(self):
                                                                      self.base_click(page.pay_my_order)
                                                               
                                                                  # 点击 立即支付
                                                                  def page_click_now_payment(self):
                                                                      # 必须先切换窗口
                                                                      self.base_switch_to_window(page.pay_my_order_title)
                                                                      # 点击立即支付
                                                                      self.base_click(page.pay_now_payment)
                                                               
                                                                  # 点击 货到付款
                                                                  def page_click_pay_on_delivery(self):
                                                                      # 先切换窗口
                                                                      self.base_switch_to_window(page.pay_payment_title)
                                                                      # 点击货到付款
                                                                      self.base_click(page.pay_on_delivery)
                                                               
                                                                  # 确认支付
                                                                  def page_click_payment_mode(self):
                                                                      self.base_click(page.pay_confirm_payment)
                                                               
                                                                  # 获取支付结果
                                                                  def page_get_payment_result(self):
                                                                      self.base_get_text(page.pay_payment_result)
                                                               
                                                                  # 组合支付业务方法
                                                                  def page_pay(self):
                                                                      self.page_click_my_order_link()
                                                                      self.page_click_now_payment()
                                                                      self.page_click_pay_on_delivery()
                                                                      self.page_click_payment_mode()

                                                              scripts:

                                                              • test01_login.py

                                                                import unittest
                                                                from day11_TPshop项目.base.get_driver import GetDriver
                                                                from day11_TPshop项目.base.get_logger import GetLogger
                                                                from day11_TPshop项目.page.page_login import PageLogin
                                                                from day11_TPshop项目.tools.read_txt import read_txt
                                                                from parameterized import parameterized
                                                                 
                                                                # 获取log日志器
                                                                log = GetLogger().get_logger()
                                                                 
                                                                 
                                                                def get_data():
                                                                    arrs = []
                                                                    for data in read_txt("login.txt"):
                                                                        arrs.append(tuple(data.strip().split(",")))
                                                                    return arrs[1:]
                                                                 
                                                                 
                                                                # 新建 登录测试类 并 继承 unittest.TestCase
                                                                class TestLogin(unittest.TestCase):
                                                                    # 新建 setUpClass
                                                                    @classmethod
                                                                    def setUpClass(cls) -> None:
                                                                        try:
                                                                            # 实例化 并获取 driver
                                                                            cls.driver = GetDriver.get_driver()
                                                                            # 实例化 PageLogin()
                                                                            cls.login = PageLogin(cls.driver)
                                                                            # 点击登录链接
                                                                            cls.login.page_click_login_link()
                                                                        except Exception as e:
                                                                            # 截图
                                                                            cls.login.base_get_img()
                                                                            # 日志
                                                                            log.error("错误:{}".format(e))
                                                                 
                                                                    # 新建 tearDownClass
                                                                    @classmethod
                                                                    def tearDownClass(cls) -> None:
                                                                        # 关闭driver驱动对象
                                                                        GetDriver.quit_driver()
                                                                 
                                                                    # 新建 登录测试方法
                                                                    @parameterized.expand(get_data())
                                                                    def test_login(self, username, pwd, verify_code, expect_result, status):
                                                                        try:
                                                                            # 调用 登录业务方法
                                                                            self.login.page_login(username, pwd, verify_code)
                                                                 
                                                                            # 判断是否为正向
                                                                            if status == "true":
                                                                                # 断言是否登录成功
                                                                                try:
                                                                                    self.assertTrue(self.login.page_if_login_success())
                                                                                except Exception as e:
                                                                                    # 截图
                                                                                    self.login.base_get_img()
                                                                                    # 日志
                                                                                    log.error("出错了:{}".format(e))
                                                                                # 点击 安全退出
                                                                                self.login.page_click_logout_link()
                                                                                # 点击 登录链接
                                                                                self.login.page_click_login_link()
                                                                            # 逆向用例
                                                                            else:
                                                                                # 获取错误提示信息
                                                                                msg = self.login.page_get_err_info()
                                                                                print("msg:", msg)
                                                                                try:
                                                                                    self.assertEqual(msg, expect_result)
                                                                                except Exception as e:
                                                                                    # 截图
                                                                                    self.login.base_get_img()
                                                                                    # 日志
                                                                                    log.error("出错了:{}".format(e))
                                                                                # 点击错误提示框 确定按钮
                                                                                self.login.page_click_error_alert()
                                                                        except Exception as e:
                                                                            # 截图
                                                                            self.login.base_get_img()
                                                                            # 日志
                                                                            log.error("出错了:{}".format(e))
                                                                • test02_cart.py(代码略)

                                                                • test03_order.py(代码略)

                                                                • test04_pay.py(代码略)

                                                                  run:

                                                                  • run_main.py

                                                                    # 导包
                                                                    import unittest
                                                                    import time
                                                                    from day11_tpshop.tools.HTMLTestRunner import HTMLTestRunner
                                                                     
                                                                    # 定义测试套件
                                                                    suite = unittest.defaultTestLoader.discover("../scripts/")
                                                                     
                                                                    # 报告生成目录及文件名称
                                                                    dir_path = "../report/{}.html".format(time.strftime("%Y_%m_%d %H_%M_%S"))
                                                                    # 获取文件流并调用run运行,生成测试报告
                                                                    with open(dir_path, "wb") as f:
                                                                        HTMLTestRunner(stream=f, title="TpShop商城自动化测试报告", description="操作系统:Win10")

                                                                    tools:

                                                                    • HTMLTestRunner.py

                                                                    • HTMLTestRunnerCN.py

                                                                    • read_text.py

                                                                      def read_txt(filename):
                                                                          filepath = "../data/"+filename
                                                                          with open(filepath, "r", encoding="utf-8") as f:
                                                                              return f.readlines()
                                                                       
                                                                       
                                                                      """
                                                                          问题:读出来的不是预期需要的格式
                                                                      """
                                                                       
                                                                      if __name__ == '__main__':
                                                                          print(read_txt("calc.txt"))
                                                                          print("--" * 60)
                                                                          arrs1 = []
                                                                          for data in read_txt("calc.txt"):
                                                                              arrs1.append(tuple(data.strip().split(",")))
                                                                          print("arrs1为:", arrs1)  # [(), ()]
                                                                       
                                                                          arrs2 = []
                                                                          for data in read_txt("calc.txt"):
                                                                              arrs2.append(data.strip().split(","))
                                                                          print("arrs2为:", arrs2[1::])  # [[], []]
                                                                      • read_json.py

                                                                        # 导包
                                                                        import json
                                                                         
                                                                         
                                                                        def read_json(filename):
                                                                            filepath = "../data/"+filename
                                                                            # 获取文件流 并调用load
                                                                            with open(filepath, "r", encoding="utf-8") as f:
                                                                                return json.load(f)
                                                                         
                                                                         
                                                                        """
                                                                            问题:
                                                                                需求格式:[(), ()] 或 [[], []]
                                                                            解决:
                                                                                1、新建空列表 arrs = []
                                                                                2、读取现有的 json 值,存放到列表中
                                                                        """
                                                                         
                                                                         
                                                                        if __name__ == '__main__':
                                                                            print(read_json("login.json"))
                                                                            print("--" * 60)
                                                                            # 新建空列表
                                                                            arrs1 = []
                                                                            for data1 in read_json("login.json").values():
                                                                                # print(data)
                                                                                arrs1.append((data1.get("username"),
                                                                                             data1.get("password"),
                                                                                             data1.get("verify_code"),
                                                                                             data1.get("expect")))
                                                                            print(arrs1)  # [(), ()]
                                                                            arrs2 = []
                                                                            for data2 in read_json("login.json").values():
                                                                                arrs2.append([data2.get("username"),
                                                                                             data2.get("password"),
                                                                                             data2.get("verify_code"),
                                                                                             data2.get("expect")])
                                                                            print(arrs2)  # [[], []]

                                                                        data:

                                                                        • login.txt(内容略)

                                                                        • login.json(内容略)

                                                                          image: 截图保存的文件夹(内容略)

                                                                          log: 日志收集保存的文件夹(内容略)

                                                                          report: 测试报告生成的文件夹(内容略)

                                                                          同时,在这我为大家准备了一份软件测试视频教程(含面试、接口、自动化、性能测试等),就在下方,需要的可以直接去观看。

                                                                          【2025最新版】字节大牛讲的最全最细的自动化测试全套教程!永久白嫖,拿走不谢,全程干货无废话!逼自己15天内学完,从软件测试基础到项目实战一套全通关!

免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们。

相关阅读

目录[+]

取消
微信二维码
微信二维码
支付宝二维码