项目实战(appium+selenium+po封装)
实现效果演示
1、app订单业务
2、web发货业务
项目实施
要实现的业务:app下单流程
实现技术:python+appium+selenium
结构实现:po+日志+数据驱动+报告
执行方式:持续集成
结构搭建
import os
import time
from selenium.webdriver.support.wait import WebDriverWait
from config import DIR_PATH
class Base:
# 初始化方法
def __init__(self, driver):
self.driver = driver
# 查找元素方法
def base_find(self, loc, timeout=10, poll=0.5):
return WebDriverWait(self.driver, timeout, poll).until(lambda x:x.find_element(*loc))
# 点击方法
def base_click(self, loc):
self.base_find(loc).click()
# 输入方法
def base_input(self, loc, value):
# 获取元素
el = self.base_find(loc)
# 清空
el.clear()
# 输入
el.send_keys(value)
# 获取文本方法
def base_get_text(self, loc):
return self.base_find(loc).text
# 截图方法
def base_get_img(self):
img_path = DIR_PATH + os.sep + "img" + os.sep + "{}.png".format(time.strftime("%Y%m%d%H%M%S"))
self.driver.get_screenshot_as_file(img_path)
app登录page结构
class PageAppLogin:
# 1、点击 我的
def page_app_click_me(self):
pass
# 2、点击 登录头像
def page_app_click_login_link(self):
pass
# 3、输入用户名
def page_app_input_username(self):
pass
# 4、输入密码
def page_app_input_pwd(self):
pass
# 5、点击勾选协议
def page_app_click_pro(self):
pass
# 6、点击登录按钮
def page_app_click_login_btn(self):
pass
# 7、获取登录昵称
def page_app_get_nickname(self):
pass
# 8、组合业务方法
def page_app_login(self):
pass
"""
一、以下为app登录模块配置信息
"""
# 我的
app_login_me = By.XPATH, "//*[@text='我的']"
# 登录图片(连接)
app_login_link = By.XPATH, "//*[@resource-id='com.tpshop.malls:id/head_img']"
# 用户名
app_username = By.XPATH, "//*[@resource-id='com.tpshop.malls:id/mobile_et']"
# 密码
app_pwd = By.XPATH, "//*[@resource-id='com.tpshop.malls:id/pwd_et']"
# 协议
app_pro = By.XPATH, "//*[@resource-id='com.tpshop.malls:id/agree_btn']"
# 登录按钮
app_login_btn = By.XPATH, "//*[@resource-id='com.tpshop.malls:id/login_tv']"
# 昵称
app_nickname = By.XPATH, "//*[@resource-id='com.tpshop.malls:id/nick_name_tv']"
登录script实现
import unittest
from page.page_app_login import PageAppLogin
from util import GetDriver
class TestAppLoginOrder(unittest.TestCase):
def setUp(self) -> None:
self.driver = GetDriver.get_app_driver()
# 获取PageAppLogin实例
self.app = PageAppLogin(self.driver)
def tearDown(self) -> None:
self.driver.quit()
def test01_login_order(self):
# 调用登录
self.app.page_app_login()
# 打印昵称->断言
nickname = self.app.page_app_get_nickname()
print("登录账户昵称为:", nickname)
# 提示:获取昵称需要加个强制等待时间 2
订单业务结构搭建(page_order.py)
class PageAppOrder:
# 点击首页
def page_app_click_index(self):
pass
# 点击搜索框
def page_app_click_search_text(self):
pass
# 输入搜索内容
def page_app_input_search_text(self):
pass
# 点击搜索按钮
def page_app_click_search_btn(self):
pass
# 选择商品
def page_app_select_photo(self):
pass
# 点击加入购物车
def page_app_add_cart(self):
pass
# 点击确定
def page_app_cart_ok(self):
pass
# 点击购物车
def page_app_click_cart(self):
pass
# 点击立即购买
def page_app_now_purchase(self):
pass
# 点击提交订单
def page_app_click_submit_order(self):
pass
# 点击 立即支付
def page_app_click_now_pay(self):
pass
# 输入 密码
def page_app_input_pwd(self):
pass
# 点击确定
def page_app_click_sure(self):
pass
# 获取订单编号
def page_app_get_order_on(self):
pass
# 下单业务方法
def page_app_order(self):
pass
Base类
说明:由于web发货页面需要切换iframe标签,所以在Base类中新增两个方法(1、切换frame2、回到默认目录)
# 切换frame
def base_switch_frame(self, loc):
# 获取元素
el = self.base_find(loc)
# 执行切换
self.driver.switch_to.frame(el)
# 恢复frame
def base_default_frame(self):
self.driver.switch_to.default_content()
Page类
结构搭建(page_web_login.py)
class PageWebLogin:
# 1、输入用户名
def page_web_username(self):
pass
# 2、输入密码
def page_web_pwd(self):
pass
# 3、输入验证码
def page_web_verify_code(self):
pass
# 4、点击登录按钮
def page_web_login_btn(self):
pass
# 5、获取登录昵称
def page_web_nickname(self):
pass
# 登录业务方法
def page_web_login(self):
pass
"""
三、web后台登录配置信息整理
"""
# 用户名
web_login_username = By.CSS_SELECTOR, "[name='username']"
# 密码
web_login_pwd = By.CSS_SELECTOR, "[name='password']"
# 验证码
web_login_verify = By.CSS_SELECTOR, "[name='vertify']"
# 登录按钮
web_login_submit = By.CSS_SELECTOR, "[name='submit']"
# 昵称
web_login_nickname = By.CSS_SELECTOR, ".bgdopa-t"
driver封装
# 获取Web Driver
@classmethod
def get_web_driver(cls):
if cls.__web_driver is None:
cls.driver = webdriver.Chrome()
cls.driver.get(HOST)
cls.driver.maximize_window()
return cls.driver
发货Page页面实现
import page, time
from base.base import Base
class PageWebOrder(Base):
# 订单菜单
def page_web_order_menu(self):
self.base_click(page.web_order)
# 左侧 发货单
def page_web_order_goods(self):
self.base_click(page.web_order_goods)
# 工作区域 去发货
def page_web_go_goods(self):
# 切换iframe
self.base_switch_frame(page.web_order_iframe)
self.base_click(page.web_order_go_goods)
# 物流公司
def page_order_company(self):
self.base_click(page.web_order_company)
# 配送单号
def page_order_input_order_no(self):
value = str(time.strftime("%Y%m%d%H%M%S"))
self.base_input(page.web_order_order_no, value)
# 确认发货
def page_order_goods_ok(self):
self.base_click(page.web_order_goods_ok)
# 打印配置单
def page_order_print_order(self):
self.base_click(page.web_order_print_order)
# 获取订单编号
def page_order_get_on(self):
return self.base_get_text(page.web_order_on)
# 订单发货业务
def page_order_go_goods(self):
self.page_web_order_menu()
self.page_web_order_goods()
self.page_web_go_goods()
self.page_order_company()
self.page_order_input_order_no()
self.page_order_goods_ok()
self.page_order_print_order()
Script类
test02_web_login_order.py
- 登录
import unittest
from time import sleep
from page.page_web_login import PageWebLogin
from util import GetDriver
class TestWebLoginOrder(unittest.TestCase):
def setUp(self) -> None:
self.driver = GetDriver.get_web_driver()
self.login = PageWebLogin(self.driver)
def tearDown(self) -> None:
sleep(1)
self.driver.quit()
def test01_web_login_order(self):
self.login.page_web_login()
nickname = self.login.page_web_nickname()
print("登录后的昵称为:",nickname)
- 订单配置信息整理
# 订单菜单
web_order = By.XPATH, "//a[text()='订单']"
# 左侧菜单 发货单
web_order_goods = By.XPATH, "//a[text()='发货单']"
# iframe
web_order_iframe = By.CSS_SELECTOR, "#workspace"
# 去发货 //div[text()='202112161517008312']/../..//td[@class='handle']//a[1]
web_order_go_goods = By.XPATH, "//a[text()='去发货']"
# 物流公司
web_order_company = By.CSS_SELECTOR, "[value='YZPY']"
# 配送单号
web_order_order_no = By.CSS_SELECTOR, "#invoice_no"
# 确认发货
web_order_goods_ok = By.CSS_SELECTOR, "ncap-btn-send"
# 打印配置单
web_order_print_order = By.CSS_SELECTOR, ".fa-print"
# 获取订单编号
web_order_on = By.XPATH, "//div[@id='printDiv']/div[@class='contact-info']/dl[1]/dd[2]"
# 难点:如何根据指定单号,查找对应的去发货元素?
# 思路:想找共同的父级,在逐级查找
- 订单发货
import unittest
from time import sleep
import page
from page.page_web_login import PageWebLogin
from page.page_web_order import PageWebOrder
from util import GetDriver
class TestWebLoginOrder(unittest.TestCase):
def setUp(self) -> None:
self.driver = GetDriver.get_web_driver()
self.login = PageWebLogin(self.driver)
self.order = PageWebOrder(self.driver)
def tearDown(self) -> None:
sleep(1)
self.driver.quit()
def test01_web_login_order(self):
try:
# 登录
self.login.page_web_login()
nickname = self.login.page_web_nickname()
print("登录后的昵称为:", nickname)
# 发货
self.order.page_order_go_goods()
# 打印订单
order_no = self.order.page_order_get_on()
print("发货的订单为:", order_no)
# self.assertEqual(page.order_on,order_no)
except Exception as e:
print("错误原因:",e)
raise
日志封装
# 日志封装
class GetLog:
__log = None
@classmethod
def get_log(cls):
if cls.__log is None:
# 获取日志器
cls.__log = logging.getLogger()
# 设置入口级别
cls.__log.setLevel(logging.INFO)
# 获取处理器
filename = DIR_PATH + os.sep + "log" + os.sep + "tpshop_auto.log"
tf =logging.handlers.TimedRotatingFileHandler(filename=filename,
when="midnight",
interval=1,
backupCount=3,
encoding="utf-8")
# 获取格式器
fmt = "%(asctime)s %(levelname)s [%(filename)s(%(funcName)s:%(lineno)d)] - %(message)s"
fm = logging.Formatter(fmt)
# 将格式器添加到处理器
tf.setFormatter(fm)
# 将处理器添加到日志器
cls.__log.addHandler(tf)
# 返回日志器
return cls.__log
# 日志应用
1、记录程序运行步骤 base->info
2、记录程序错误 script->error
持续集成
- 报告无样式问题
System.setProperty("hudson.model.DirectoryBrowserSupport.CSP", "")