PO来源
- PageObject
- https://github.com/SeleniumHQ/selenium/wiki/PageObjects
- 《Head First 设计模式》 《Head First 设计模式(中文版)(Jolt震撼大奖 经典畅销书 深入浅出讲清设计模式)》(Eric Freeman &Elisabeth Freeman with Kathy Sierra & Bert Bates 著 O)【简介_书评_在线阅读】 - 当当图书
- 《重构》 《重构 改善既有代码的设计 Java语言版》([美]Martin Fowler 著)【简介_书评_在线阅读】 - 当当图书
- 演练代码地址:https://github.com/seveniruby/appium_online_9
!(https://martinfowler.com/bliki/images/pageObject/pageObject.png =400x)
When you write tests against a web page, you need to refer to elements within that web page in order to click links and determine what’s displayed. However, if you write tests that manipulate the HTML elements directly your tests will be brittle to changes in the UI. A page object wraps an HTML page, or fragment, with an application-specific API, allowing you to manipulate page elements without digging around in the HTML.
当您针对网页编写测试时,您需要引用该网页中的元素以单击链接并确定显示的内容。但是,如果您编写直接操作HTML元素的测试,则测试对UI的更改将很脆弱。页面对象使用特定于应用程序的API包装HTML页面或片段,允许您操作页面元素而无需在HTML中进行挖掘。
If you have WebDriver APIs in your test methods, You’re Doing It Wrong. – Simon Stewart.
PO几个原则
- The public methods represent the services that the page offers
- Try not to expose the internals of the page
- Generally don’t make assertions
- Methods return other PageObjects
- Need not represent an entire page
- Different results for the same action are modelled as different methods
代码
Appium Driver封装
from appium import webdriver
from appium.webdriver.webdriver import WebDriver
class AndroidClient(object):
driver:WebDriver
@classmethod
def install_app(cls) -> WebDriver:
caps = {}
#如果有必要,进行第一次安装
# caps["app"]=''
caps["platformName"] = "android"
caps["deviceName"] = "hogwarts"
caps["appPackage"] = "com.xueqiu.android"
caps["appActivity"] = ".view.WelcomeActivityAlias"
#解决第一次启动的问题
caps["autoGrantPermissions"] = "true"
# caps['noReset']=True
cls.driver = webdriver.Remote("http://localhost:4723/wd/hub", caps)
cls.driver.implicitly_wait(10)
return cls.driver
@classmethod
def restart_app(cls) -> WebDriver:
caps = {}
caps["platformName"] = "android"
caps["deviceName"] = "hogwarts"
caps["appPackage"] = "com.xueqiu.android"
caps["appActivity"] = ".view.WelcomeActivityAlias"
#为了更快的启动,并保留之前的数据,从而可以保存上一个case执行后的状态
caps['noReset']=True
caps['chromedriverExecutableDir']="/Users/seveniruby/projects/chromedriver/2.20"
#caps["udid"]="emulator-5554"
cls.driver = webdriver.Remote("http://localhost:4723/wd/hub", caps)
cls.driver.implicitly_wait(10)
return cls.driver
Page封装
from page_object.driver.AndroidClient import AndroidClient
from page_object.page.SelectedPage import SelectedPage
class MainPage(object):
#调用appium启动app
def __init__(self):
AndroidClient.restart_app()
def gotoSelected(self):
#调用全局的driver对象使用webdriver api操纵app
AndroidClient.driver.find_element_by_xpath("//*[@text='自选']")
AndroidClient.driver.find_element_by_xpath("//*[@text='自选']").click()
return SelectedPage()
另外一个Page
from page_object.driver.AndroidClient import AndroidClient
class SelectedPage(object):
def addDefault(self):
return self
def getPriceByName(self, name) -> float:
#todo:
price=AndroidClient.driver\\
.find_element_by_xpath("//*[contains(@resource-id, 'stockName') and @text='"+name+"']"+
"/../../..//*[contains(@resource-id, 'currentPrice')]").text
return float(price)
testcase
import pytest
from page_object.page.MainPage import MainPage
class TestSelected(object):
def test_price(self):
main=MainPage()
assert main.gotoSelected().getPriceByName("科大讯飞")==28.83
`
作业1
点击雪球行情,获得“深证成指”的指数,判断是否大于8000点
作业2
参考github代码