介绍
本文章没有营养…不推荐阅读…我写来当笔记的…
- PO是Page Object的缩写
- 业务流程与页面元素操作分离的模式,可以简单理解为每个页面下面都有一个配置class, 配置class就用来维护页面元素或操作方法。
- 提高测试用例的可维护性、可读取性
分层思想
PO模式代码编写
以一个登陆页面来举例
- 分别定义对象层
Page_Login
类, 用于元素定位; - 操作层
Operate_Login
类, 用于元素操作 - 业务层
Test_login
类, 用于测试用例 Base_Page
类是基础类, 可以将当前页面需要用到的Driver方法封装起来, 如等待、点击等操作。 然后Page_login
可以通过继承Base_Page
, 减少重复代码
示例
基础类:
from selenium.webdriver.common.by import By
from logUtil import my_log
from selenium.webdriver.support.wait import WebDriverWait
# 定义基础类
class Action:
def __init__(self, driver):
self.driver = driver
self.log = my_log("BasePage")
# 定义操作方法
def by_xpath_click(self, value):
"""xpath点击操作"""
self.by_find_element(By.XPATH, value).click()
def by_id_click(self, value):
"""id点击操作"""
self.by_find_element(By.ID, value).click()
def by_id_send_keys(self, value, send_value):
"""通过ID定位元素并发送内容"""
self.by_find_element(By.ID, value).send_keys(send_value)
# webDriverWait
def by_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)
def get_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 BasePage import Action
class BxgMainPage(Action):
# "我的"按钮
me_xpath = "//*[contains(@text, '我的')]"
# "我的按钮"点击
def allow_click(self):
self.by_xpath_click(self.me_xpath)
操作登录页面的类
它负责封装选择登录方式、输入账号密码、点击登录按钮、获取toast等元素定位和操作
from BasePage import Action
class BxgLoginPages(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 = "错误"
def login_method_click(self):
self.by_id_click(self.login_method)
def login_type_click(self):
self.by_id_click(self.login_type)
def login_method_click_2(self):
self.by_id_click(self.login_method_2)
def account_send(self, value):
self.by_id_send_keys(self.account, value)
def pwd_send(self, value):
self.by_id_send_keys(self.password, value)
def login_btn_click(self):
self.by_id_click(self.login_btn)
def toast(self):
return self.get_toast(self.toast_xpath)
最后是测试用例的编写
import unittest
from utils.Yamlutil import YamlReader
from appium import webdriver
from page.page_main import BxgMainPage
from page.page_login import BxgLoginPages
# PO模式+unittest
class Login(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类, 用于点击登录方式和输入账号密码
@classmethod
def setUpClass(cls) -> None:
super().setUpClass()
pass
@classmethod
def tearDownClass(cls) -> None:
super().tearDownClass()
pass
# 定义测试用例方法
def test_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工具类
完整代码:
码云仓库