背景

最近在研究 Python——Appium 的自动化实现,大概两个多月吧,感觉现在遇到了一些瓶颈,想请社区的牛人给一个方向,主要还是关于设计模式的。

现在的进度

正常的线性代码完成 Android 原生和混合 App 是没问题了,在写的过程中我发现实用性并不大,开发一点很小的变动我的代码就要做大改。感觉很麻烦,于是找了一个叫 Page Object 的设计模式,按照这个模式写,我现在实现了这么些东西。源代码在这里WeStockTest,还没写完。

元素

因为就我一个人,我就直接使用配置文件处理,代码如下:

CONNECT = {
    'platformName': 'Android',
    'platformVersion': '4.4.4',
    'deviceName': '5136b01e',
    'appPackage': 'com.weizq',
    'appActivity': 'com.zztzt.android.simple.app.MainActivity',
    "baseUrl": "http://127.0.0.1:4723/wd/hub"
}

COMMON = {
    'native_caixun': (By.NAME, u'财讯'),
    'native_hangqing': (By.NAME, u'行情'),
    'native_faxian': (By.NAME, u'发现'),
    'native_wo': (By.NAME, u'我'),
    'data_url': '/Users/SvenWeng/PycharmProjects/WeStock/Data/data.json',
    'view_title': (By.CLASS_NAME, 'android.widget.TextView')
}

公共方法

class WebDdriver(object):
    def __init__(self, driver):
        self.driver = driver

    def __str__(self):
        return 'webDdriver'

    def find_element(self, *loc):
        """
        定位元素,定位正确后返回元素的信息,外部调用传入元组参数必须有*,
        例如:
        find_element(*self.native_caixun)

        :param loc: 元组类型,结构必须是(By.NAME, u'财讯')
        :return: element
        """
        try:
            element = WebDriverWait(self.driver, 10).until(lambda x: x.find_element(*loc))
            return element
        except NoSuchElementException, e:
            print 'Error details :%s' % (e.args[0])

    def find_elements(self, *loc):
        """
        定位元素,定位正确后返回元素的信息,外部调用传入元组参数必须有*,
        例如:
        find_elements(*self.native_caixun)

        :param loc: 元组类型,结构必须是(By.NAME, u'财讯')
        :return: elements
        """
        try:
            # return self.driver.find_elements(*loc)
            elements = WebDriverWait(self.driver, 10).until(lambda x: x.find_elements(*loc))
            return elements
        except NoSuchElementException, e:
            print 'Error details :%s' % (e.args[0])

单个页面的方法

class Caixun(AppUI):

    # ----------------------财讯所有数据--------------------------
    native_caixun = config.COMMON['native_caixun']

    tuijian = config.CAIXUN['tuijian']
    gupiao = config.CAIXUN['gupiao']
    jijin = config.CAIXUN['jijin']
    zhaiquan = config.CAIXUN['zhaiquan']
    xinsanban = config.CAIXUN['xinsanban']
    neirong = config.CAIXUN['zixunneirong']
    plusbtn = config.CAIXUN['jiahao']
    pindao = config.CAIXUN['pindao']

    img_url = config.CAIXUN['imgurl']

    # ----------------------------------------------------------

    # ---------------------执行方法------------------------------

    def clickCaixun(self):
        """
        点击底部导航的财讯
        :return:None
        """
        self.find_element(*self.native_caixun).click()
        time.sleep(2)

    def get_screen(self, name):
        """
        对当前屏幕截图,函数中调用了getScreenshot,在上方定义常量的时候必须定义img_url
        :param name: 保存图片的名称
        :return:None
        """
        self.getScreenshot(name, self.img_url)

    def clickTuijian(self):
        """
        点击推荐
        :return: None
        """
        self.find_element(*self.tuijian).click()

    def clickGupiao(self):
        """
        点击股票
        :return: None
        """
        self.find_element(*self.gupiao).click()

测试步骤

class CaixunTest(AppTestCase, Caixun):

    def testAClickTitle(self):
        """测试财讯的频道内容是否正确"""
        self.clickCaixun()
        self.assertEqual(self.get_title(), u'财讯')
        self.clickTuijian()
        self.get_screen('tuijian')
        self.clickNeirong()
        self.get_screen('tuijianneirong')
        self.sysback()
        self.clickGupiao()
        self.get_screen('gupiao')
        self.clickNeirong()
        self.get_screen('gupiaoneirong')
        self.sysback()
        self.clickJijin()
        self.get_screen('jijin')
        self.clickNeirong()
        self.get_screen('jijinneirong')
        self.sysback()
        self.clickZhaiquan()
        self.get_screen('zhaiquan')
        self.clickNeirong()
        self.get_screen('zhaiquanneirong')
        self.sysback()
        self.clickXinsanban()
        self.get_screen('xinsanban')
        self.clickNeirong()
        self.get_screen('xinsanbanneirong')

    def testBAddPindao(self):
        """测试增加频道功能"""
        self.clickCaixun()
        self.clickPlus()
        self.assertEqual(self.get_title(), u'频道管理')
        # 校验推荐不可点击
        self.assertFalse(self.checkTuijianEnabled())
        # 校验其他可以点击
        self.assertTrue(self.checkOtherAbled())

        text = self.clickTextItem()
        self.assertEqual(text, self.getFifthItemText())
        self.clickItem(5)

    def testCNewPindao(self):
        """测试新增频道内容显示"""
        self.clickCaixun()
        self.clickPlus()
        text = self.clickTextItem()
        self.sysback()
        ori = self.getLocation(*config.CAIXUN['xinsanban'])
        new = self.getLocation(*config.CAIXUN['tuijian'])
        self.driver.swipe(ori[0], ori[1], new[0], new[1])
        self.find_element(*(By.NAME, text)).click()
        self.clickNeirong()
        self.get_screen(text)

困惑

现在最大的困惑就是再怎么走下去,和一个朋友聊的时候他说这个迷茫期是很正常的,说明处在一个比较正常的十字路口,但是下一步怎么走他也没说。

我说说几个比较明确的疑问吧:

  1. 我这种设计方式有哪些比较严重的缺陷?(我自己感觉除了抽离出元素,好像和线性撸代码差别不是特别的大)
  2. 我想过关键字驱动的方法,但是步骤中有很多地方涉及到流程的控制,我没太明白这一块要怎么去设计
  3. 关于 Android 的性能方面要如何提升?参考群里的优质帖子,我自己也写了一个监控工具:《AndroidTools》,但是具体这些指标都是死的,不太明白哪些场景应该用哪些手段来测试哪些指标。


↙↙↙阅读原文可查看相关链接,并与作者交流