回顾上节课知识点及作业
显式等待:
WebDriverWait(driver, timeout).until() 等待直到某个元素出现
WebDriverWait(driver, timeout).until_not() 等待 直到某个元素消失
# 8、验证删除成功
WebDriverWait(self.driver, 15).until_not(lambda x:x.find_element_by_xpath(f"//*[@text='{username}']"))
其它定位方式:
- 坐标定位: 不建议
- 图片匹配
参数化与数据驱动
PO模式回顾
- 方法意义
- 用公共方法代表UI所提供的服务
- 方法应该返回其他的PageObject或者返回用于断言的数据
- 同样的行为不同的结果可以建模为不同的方法
- 不要在方法内加断言
- 字段意义
- 不要暴露页面内部的元素给外部
- 不需要建模UI内的所有元素
使用PO改造用例
- 封装1: 搭架子
base/
testcases/
前台业务写完,后面不需要再做任何修改,除非前台的业务逻辑需要变化,否则 不需要改动。
- 封装2:
1、BasePage封装, 将所有的页面的init方法都使用BasePage里面的init方法,
2、复用driver
在app.py start()方法里面添加下面的判断 :
def start(self):
if self.driver == None:
caps = {}
caps["deviceName"] = "emulator-5554"
caps["platformName"] = "Android"
caps["appPackage"] = "com.tencent.wework"
caps["appActivity"] = ".launch.LaunchSplashActivity"
caps["noReset"] = "true"
# 最重要代码,创建驱动
self.driver = webdriver.Remote("http://localhost:4723/wd/hub", caps)
else:
self.driver.launch_app()
self.driver.implicitly_wait(10)
return self
-
launch_app与 start_activity 区别?
- launch_app() 启动的是desirecap里面定义的 activity, 不需要传参数
- self.driver.start_activity(“com.example”, “ActivityName”); 必须传入两个参数,一个是package, 另一个activity , 可以启动任何应用的任何页面
-
封装3
basepage.py 增加一些基层的常用方法,根据业务需求,封装你自己需要的方法。
class BasePage:
driver: WebDriver
def __init__(self, driver: WebDriver = None):
self.driver = driver
# 查找元素
def find(self, locator):
return self.driver.find_element(*locator)
def find_by_scroll(self, text):
return self.driver.find_element(MobileBy.ANDROID_UIAUTOMATOR,
f'new UiScrollable(new UiSelector().scrollable(true)\
.instance(0)).scrollIntoView(new UiSelector().\
text("{text}").instance(0));')
def find_and_click(self, locator):
self.find(locator).click()
def get_toast(self):
return self.driver.find_element_by_xpath("//*[@class='android.widget.Toast']").text
def back(self, num=1):
for i in range(num):
self.driver.back()