51Testing软件测试论坛

标题: 移动端自动化测试系列之四——生成定位元素 [打印本页]

作者: 巴黎的灯光下    时间: 2017-6-30 14:16
标题: 移动端自动化测试系列之四——生成定位元素
前言
之所以把定位元素单独拎出来说,是因为我觉得在写移动端测试框架的时候,如果处理不好的话,元素的定位是比较麻烦的事情.

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

.id
.name
.xpath
.tag_name


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

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

PyYAML

安装
  1. pip3 install PyYAML
复制代码
用于解析 yaml 文件

使用方法非常简单:
  1. def parse():
  2.     L.i('解析page.yaml, Path:' + pages_path)
  3.     with open(pages_path, 'r', encoding='utf-8') as f:
  4.         return yaml.safe_load(f)
复制代码
这样就可以把 yaml 文件的内容解析成一个对象
watchdog

安装
  1. pip3 install watchdog
复制代码
用于监听某文件是否发生变化,一旦发生变化(保存,删除等)既执行回掉.

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

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

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

使用方法

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

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

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

开启文件监听
执行项目中的 watch_dog.py
  1. python3 watch_dog.py
复制代码
定位元素
打开在项目中的pages.yaml文件写入如下内容:
  1. ---
  2. LoginPage:
  3.   dec: 登录页面
  4.   locators:
  5.     -
  6.       name: 注册
  7.       timeOutInSeconds: 20
  8.       type: name
  9.       value: 注册
复制代码
保存该文件

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

使用元素
使用元素也很简单,下面是点击元素的方法:
  1. action.click(LoginPage.登录)
复制代码
yaml配置说明
LoginPage : 主要标识元素所属页面
dec:描述页面,可以省略
locators - name: 定位元素的名称
locators - timeOutInSeconds: 超时时间,重试查找的时间,省略后默认是20秒
locators - type: 定位元素方式
locators - value:定位元素的值





欢迎光临 51Testing软件测试论坛 (http://bbs.51testing.com/) Powered by Discuz! X3.2