介绍

本文章没有营养…不推荐阅读…我写来当笔记的…

  • PO是Page Object的缩写
  • 业务流程与页面元素操作分离的模式,可以简单理解为每个页面下面都有一个配置class, 配置class就用来维护页面元素或操作方法。
  • 提高测试用例的可维护性、可读取性

分层思想
在这里插入图片描述

PO模式代码编写

以一个登陆页面来举例
在这里插入图片描述

  • 分别定义对象层Page_Login类, 用于元素定位;
  • 操作层Operate_Login类, 用于元素操作
  • 业务层Test_login类, 用于测试用例
  • Base_Page类是基础类, 可以将当前页面需要用到的Driver方法封装起来, 如等待、点击等操作。 然后Page_login可以通过继承Base_Page, 减少重复代码

示例

基础类:

from selenium.webdriver.common.byimport Byfrom logUtilimport my_logfrom selenium.webdriver.support.waitimport WebDriverWait# 定义基础类classAction:def__init__(self, driver):
        self.driver= driver
        self.log= my_log("BasePage")# 定义操作方法defby_xpath_click(self, value):"""xpath点击操作"""
        self.by_find_element(By.XPATH, value).click()defby_id_click(self, value):"""id点击操作"""
        self.by_find_element(By.ID, value).click()defby_id_send_keys(self, value, send_value):"""通过ID定位元素并发送内容"""
        self.by_find_element(By.ID, value).send_keys(send_value)# webDriverWaitdefby_find_element(self, by, value, timeout=30, poll=2):"""
        隐式等待, 寻找元素
        """
        WebDriverWait(self.driver, timeout, poll).until(lambda x:x.find_element(by, value))return self.driver.find_element(by, value)defget_toast(self, text, timeout=30, poll=2):"""
        1. 使用by_find_element寻找元素, 类型xpath, value自定义
        2. WebDriverWait获取信息,
        """
        toast_log="//*[contains(@text, '{}')]".format(text)
        ele= WebDriverWait(self.driver, timeout, poll).until(lambda x: x.find_element_by_xpath(toast_log))return ele.text

由于只有一个简单的登录界面, 因此对象和操作都写到一个类里面了
操作主页的类
它负责封装"我的"按钮的元素定位和点击操作

from BasePageimport ActionclassBxgMainPage(Action):# "我的"按钮
    me_xpath="//*[contains(@text, '我的')]"# "我的按钮"点击defallow_click(self):
        self.by_xpath_click(self.me_xpath)

操作登录页面的类
它负责封装选择登录方式、输入账号密码、点击登录按钮、获取toast等元素定位和操作

from BasePageimport ActionclassBxgLoginPages(Action):
    login_method="com.boxuegu:id/other_login_btn"# 登录方式: 其他方式登录
    login_type="com.boxuegu:id/user_login_view"# 登录类型: 账号登录
    login_method_2="com.boxuegu:id/passwordLoginTv"# 再次更改登陆方式: 密码登陆
    account="com.boxuegu:id/edit_usr"# 账号
    password="com.boxuegu:id/edit_pwd"# 密码
    login_btn="com.boxuegu:id/btn_login"# 登录按钮
    toast_xpath="错误"deflogin_method_click(self):
        self.by_id_click(self.login_method)deflogin_type_click(self):
        self.by_id_click(self.login_type)deflogin_method_click_2(self):
        self.by_id_click(self.login_method_2)defaccount_send(self, value):
        self.by_id_send_keys(self.account, value)defpwd_send(self, value):
        self.by_id_send_keys(self.password, value)deflogin_btn_click(self):
        self.by_id_click(self.login_btn)deftoast(self):return self.get_toast(self.toast_xpath)

最后是测试用例的编写

import unittestfrom utils.Yamlutilimport YamlReaderfrom appiumimport webdriverfrom page.page_mainimport BxgMainPagefrom page.page_loginimport BxgLoginPages# PO模式+unittestclassLogin(unittest.TestCase):def__init__(self, methodName:str=...)->None:super().__init__(methodName)
        desired= YamlReader("../conf/appium_config.yaml").read_data()
        driver= webdriver.Remote("http://localhost:4723/wd/hub", desired)
        self.bxgmain= BxgMainPage(driver)# 实例化BxgMainPage类, 用于点击"我的"
        self.bxglogin= BxgLoginPages(driver)# 实例化的BxgLoginPages类, 用于点击登录方式和输入账号密码

    @classmethoddefsetUpClass(cls)->None:super().setUpClass()pass


    @classmethoddeftearDownClass(cls)->None:super().tearDownClass()pass# 定义测试用例方法deftest_login(self):# 编写测试用例步骤# 点击我的
        self.bxgmain.allow_click()# 选择其他登录方式
        self.bxglogin.login_method_click()# 选择账号登录
        self.bxglogin.login_type_click()# 选择密码登录
        self.bxglogin.login_method_click_2()# 输入账号
        self.bxglogin.account_send("1353333333")# 输入密码
        self.bxglogin.pwd_send("123456")# 点击登录
        self.bxglogin.login_btn_click()# 获取toast
        toast= self.bxglogin.toast()# 运行

代码里面另外使用了两个工具类:
logUtil: 日志工具类
YamlReader: Yaml工具类

完整代码:
码云仓库