巴黎的灯光下 发表于 2017-6-30 14:16:03

移动端自动化测试系列之四——生成定位元素

前言
之所以把定位元素单独拎出来说,是因为我觉得在写移动端测试框架的时候,如果处理不好的话,元素的定位是比较麻烦的事情.

如果对 Appium 稍微了解的童鞋一定知道定位元素的方式有很多种:

.id
.name
.xpath
.tag_name

这么多的查找方式如果都写在代码中如下:
find_elements_by_id(R.id.login)
find_elements_by_name('登录')
find_elements_by_xpath('//android.support.v7.widget.RecyclerView')....
# 甚至还有查单个元素的find_element_by_*的方法
如果都写在代码会有什么结果?

不直观,不利于查找
如果页面元素发生变动,比如id突然变化.但是整体case没有任何改变.我们还需要去改代码.
那么如何去解决这两个痛点,就是这篇教程的主要目的,在说到解决痛点之前,我先简单介绍几款小框架,在最后会说明为什么结合了这几款小框架就能够解决这两个痛点.如果对着几个小框架毕竟熟悉,可以直接看最后一小节.

PyYAML
安装
pip3 install PyYAML用于解析 yaml 文件

使用方法非常简单:
def parse():
    L.i('解析page.yaml, Path:' + pages_path)
    with open(pages_path, 'r', encoding='utf-8') as f:
      return yaml.safe_load(f)这样就可以把 yaml 文件的内容解析成一个对象
watchdog
安装
pip3 install watchdog用于监听某文件是否发生变化,一旦发生变化(保存,删除等)既执行回掉.

先写一个Handler
class WatchHandler(PatternMatchingEventHandler):
    # 监听文件类型
    patterns = ["*.yaml"]
   # 想要监听的文件路径
    watch_path = "/Users/mio4kon/.../pages.yaml"
    def on_created(self, event):
            # 比对看看是否真的是想要监听的文件
      if self.watch_path == event.src_path:
            L.i('监听到文件发生了变化')
      try:
            gen_page_py()
      except Exception as e:
            pass使用
if __name__ == "__main__":
    event_handler = WatchHandler()
    full_path = event_handler.watch_path
    path = full_path[:full_path.rfind('/') + 1]
    observer = Observer()
    observer.schedule(event_handler, path)
    observer.start()
    try:
      while True:
            time.sleep(1)
    except KeyboardInterrupt:
      observer.stop()
    observer.join()这样的话每当pages.yaml文件发生变化都会执行我定义的gen_page_py()方法.

这些是干什么的用的呢?后面会说到.现在只需要知道 watchdog 能做什么即可.

Jinja2
安装
pip3 install Jinja2用于生成模板代码.

使用方法

@staticmethod
   def gen_page_py():
       """
       利用jinja2生成pages.py文件
       """
       base_dir = Config.BASE_PATH_DIR
       template_loader = jinja2.FileSystemLoader(searchpath=base_dir+"/page/template")
       template_env = jinja2.Environment(loader=template_loader)
       page_list = GenPages.gen_page_list()
       _templateVars = {
         'page_list': page_list
       }
       template = template_env.get_template("pages")
       with open(base_dir+'/page/pages.py', 'w', encoding='utf-8') as f:
         f.write(template.render(_templateVars))效果
之所以要用到上面这三个框架.目的是为了将元素定位简单化.并将定位的方式从代码中抽离.方便查找以及修改用例

之前说的两个痛点,我在最初学习 Appium 的时候就深有体会,于是我搜寻了很多相关的测试框架,最终找到一种我认为比较科学的解决方式,其实这个解决方式还是之前在写java测试框架时看过的某一款框架(patatiumAppUi)中用到的方式,不过其作者使用的是xml来定位元素,而且在使用方式上也略微麻烦一点,如果你还有更好的想法,希望能分享出来.

总之通过上述三个框架组合最终不仅解决了上面两个痛点,而且非常易于添加新的元素查找.具体使用方式如下.

开启文件监听
执行项目中的 watch_dog.py
python3 watch_dog.py定位元素
打开在项目中的pages.yaml文件写入如下内容:
---
LoginPage:
dec: 登录页面
locators:
    -
      name: 注册
      timeOutInSeconds: 20
      type: name
      value: 注册保存该文件

至此,文件定位已经完成了.剩下要做的就是在case中用到这个定位的元素了.

使用元素
使用元素也很简单,下面是点击元素的方法:
action.click(LoginPage.登录)yaml配置说明
LoginPage : 主要标识元素所属页面
dec:描述页面,可以省略
locators - name: 定位元素的名称
locators - timeOutInSeconds: 超时时间,重试查找的时间,省略后默认是20秒
locators - type: 定位元素方式
locators - value:定位元素的值
页: [1]
查看完整版本: 移动端自动化测试系列之四——生成定位元素