标题
App 企业微信实战
PPT
课程价值
- 了解 PO模式
- 使用 PO 模式封装框架
大纲
- 元素定位
- PO模式介绍
- 企业微信实战2
脚本编写
应用
PO 封装
- 方法意义
- 用公共方法代表UI所提供的服务
- 方法应该返回其他的PageObject或者返回用于断言的数据
- 同样的行为不同的结果可以建模为不同的方法
- 不要在方法内加断言
- 字段意义
- 不要暴露页面内部的元素给外部
- 不需要建模UI内的所有元素
PO 改造流程
1、改造1:搭建起来PO 模式的架构,将业务逻辑先写出来,后面不需要改动,除非业务逻辑发生变化
2、改造2:填充业务逻辑,前端业务流程不变,只变后台逻辑
3、改造3:BasePage 封装,初始化driver
4、改造4:app.py 页面封装,复用driver , 判断 driver 是否为None, 如果 为None, 则创建一个driver, 否则 复用之前的driver , 使用 self.driver.launch_app()
启动app
5、改造5:BasePage 封装, find, find_and_click(), find_and_get_text,find_and_send_keys(), webdriverwait, gettoast_text …
练习
- 使用PO模式封装 添加联系人和删除联系人
pythonProject.zip (31.0 KB)
base_page.py
class BasePage:
TOAST_TIPS = AppiumBy.XPATH, "//*[@class='android.widget.Toast']"
def __init__(self, driver: WebDriver = None):
"""
初始化driver
:param driver:
"""
self.driver = driver
def find(self, by, value):
"""
查找元素并返回
:param by:
:param value:
:return:
"""
return self.driver.find_element(by, value)
def find_and_click(self, by, value):
"""
查找元素并点击
:param by:
:param value:
:return:
"""
self.find(by, value).click()
def find_and_send(self, by, value, text):
"""
查找元素并输入
:param by:
:param value:
:param text:
:return:
"""
self.find(by, value).send_keys(text)
def set_implicitly_wait(self, time=1):
"""
设置隐士等待
:param time:
:return:
"""
self.driver.implicitly_wait(time)
def get_toast_tips(self):
"""
获取toast信息
:return:
"""
return self.find(*self.TOAST_TIPS).text
def swipe_find(self, text, max_num=5):
"""
滑动查找文本text
:param text:
:param max_num:
:return:
"""
self.set_implicitly_wait()
# 滑动查找
for num in range(max_num):
try:
element = self.driver.find_element(AppiumBy.XPATH, f"//*[@text='{text}']")
sleep(1)
return element
except NoSuchElementException as e:
print("未找到元素")
# 获取屏幕大小
size = self.driver.get_window_size()
width = size.get("width")
height = size.get("height")
start_x = width / 2
start_y = height * 0.8
end_x = width / 2
end_y = height * 0.2
self.driver.swipe(start_x, start_y, end_x, end_y, 2000)
if num == max_num - 1:
self.set_implicitly_wait(10)
# 执行最大次数,仍然没有找到文本,抛异常
raise NoSuchElementException(f"找了{num}次,还是没有找到,请确认当前页面是否存在")
wework_app.py
class App(BasePage):
def start(self):
"""
启动app
:return:
"""
if self.driver == None:
# 准备资源
# 定义一个字典
caps = {}
# 被测手机的平台
caps["platformName"] = "Android"
caps["deviceName"] = "127.0.0.1:11509"
# 包名和activity名称
# adb logcat ActivityManager:I | findstr "cmp"
# adb logcat ActivityManager:I | grep "cmp"
caps["appPackage"] = "com.tencent.wework"
caps["appActivity"] = ".launch.LaunchSplashActivity"
# 防止清空缓存
caps["noReset"] = "true"
# 初始化driver
self.driver = webdriver.Remote("http://127.0.0.1:4723/wd/hub", caps)
# 设置隐士等待
self.set_implicitly_wait(10)
else:
# 只启动当前测试的应用
self.driver.launch_app()
def restart(self):
"""
重启
:return:
"""
pass
def stop(self):
"""
停止app
:return:
"""
pass
def goto_main(self):
"""
进入app首页
:return:
"""
return MainPage(self.driver)
main_page.py
class MainPage(BasePage):
TAB_CONTACT = AppiumBy.XPATH, "//*[@text='通讯录']"
def goto_contact_page(self):
"""
进入通讯录界面
:return:
"""
self.find_and_click(*self.TAB_CONTACT)
return ContactPage(self.driver)
contact_page.py
class ContactPage(BasePage):
def goto_add_member_page(self):
"""
进入添加成员界面
:return:
"""
self.swipe_find("添加成员").click()
return AddMemberPage(self.driver)
add_member_page.py
class AddMemberPage(BasePage):
TEXT_ADDMEMBER_MENUAL = AppiumBy.XPATH, "//*[@text='手动输入添加']"
def goto_edit_contact_page(self):
"""
进入到编辑成员界面
:return:
"""
self.find_and_click(*self.TEXT_ADDMEMBER_MENUAL)
from page.edit_contact_page import EditContactPage
return EditContactPage(self.driver)
edit_contact_page.py
class EditContactPage(BasePage):
INPUT_NAME = AppiumBy.XPATH, "//*[@text='姓名 ']/../*[@text='必填']"
INPUT_PHONE_NUMBER = AppiumBy.XPATH, "//*[@text='手机 ']/..//*[@text='必填']"
BTN_SAVE = AppiumBy.XPATH, "//*[@text='保存']"
def edit_member(self, name, phone_number):
"""
输入姓名手机号,点击保存
:param name:
:param phone_number:
:return:
"""
# 输入【姓名】【手机号】
self.find_and_send(*self.INPUT_NAME, name)
self.find_and_send(*self.INPUT_PHONE_NUMBER, phone_number)
# 点击【保存】
self.find_and_click(*self.BTN_SAVE)
from page.add_member_page import AddMemberPage
return AddMemberPage(self.driver)
test_contact.py
class TestContact:
def setup_class(self):
# mocks数据
self.faker = Faker("zh_CN")
def setup(self):
self.app = App()
self.main_page = self.app.start().goto_main()
def test_addcontact(self):
"""
添加成员
:return:
"""
name = self.faker.name()
phone_number = self.faker.phone_number()
# 添加成员并获取tips值
tips = self.main_page\
.goto_contact_page()\
.goto_add_member_page()\
.goto_edit_contact_page()\
.edit_member(name, phone_number)\
.get_toast_tips()
# 断言结果
assert "添加成功" == tips