线上第九期_PageObject 设计模式_20190525

PO来源

!(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代码