开源项目:小红书移动 UI 并发自动化测试实践之 DisCartierEJ

@ Arthor: Juan Liu
@ Date : 2017.06.03

相关背景

随着小红书发展,各种自动化产品也在逐渐使用,提高工作效率、节省时间,也更多的保证了正确性。在小红书,移动 UI 自动化方面,尝试的项目之一就是当前的这个 DisCartierEJ 项目。

在这个项目进行两个月左右的时候,我写了一篇文章总结了当时的思路小红书自动化平台实践之 Cartier,主要是讲解了思路方面和架构方面,这次更多的是关注代码方面,在架构方面也有了一点点改进。

开源背景

  1. 项目基本上达到了预期的目标,可以无连接的实现多台设备同时并行正确运行。
  2. 开源出来,希望在大家使用的过程中,更加的优化项目和代码。
  3. 实习快结束了,开源也是一次回头过来好好看看设计思路和代码的过程,优化交付给下一位同事。

github 地址

DisCartierEJ 的地址:https://github.com/haifengrundadi/DisCartierEJ

CartierEJ 的地址:https://github.com/haifengrundadi/CariterEJ

DisCartierEJ 的优点

  1. 利用 docker 将 appium 及其依赖的工具放在一个容器中,这样使用者(比如开发或者其他相关测试人员等)只需要 pull 镜像文件,就可以运行了,不需要一个个去安装各种依赖,减去不必要的时间。ps:我刚接触的时候,花了一天多的时间装了各种软件,遇到各种配置问题,更会浪费许多时间,这些时间对仅仅使用的人来说,毫无必要,对需要开发的人来说,犯错还是有价值的。

  2. 利用 stf 管理设备,这样不管你在哪都可以进行使用手机,不必每次都将手机通过 usb 连接计算机。更为重要的是,你可以任意选择你想要的手机,选择多台同时运行,相当于一个资源池的概念。ps:你在出差,你身边没有手机,突然想运行一个 case,这个时候打开电脑,运行就好。

  3. 多台并行运行 case。之前,都是一个计算机上运行一个 appium,一个 appium server 对应一个 device,很难将一个 case 一下子运行在多个设备上,测试兼容性不是很方便。

  4. 在 jenkins 可以进行巡检,并将结果通过展示出来,(这个还没有实现,有尝试过,但是没有办法把本地运行 stf 的机器(需要将手机本地连接到一个主机上)当做腾讯云的一个 slave,而暂时暂停(ssh 连接,如果通过域名,应该是可以作为一个 slave 的))。

DisCartierEJ 的架构

上图是 DisCartierEJ 的架构图,下面根据一个使用者的流程对这个图进行介绍。

  1. 深蓝色部分,用户希望自己的 case 在三台设备上跑一下。
  2. 将自己 case pull 到 github 或者能下载的地方

    https://github.com/haifengrundadi/CartierEJ.git

  3. git clone DisCartierEJ 代码

    git clone https://github.com/haifengrundadi/DisCartierEJ.git

  4. 将 DisCartierEJ 中的 Dockerfile 中的获取 CartierEJ 的代码更改为步骤 2 的地址,并生成对应的镜像。

    ...
    #=======================================
    # pull code from git
    #=======================================
    RUN git clone https://github.com/haifengrundadi/CartierEJ.git
    ...

    生成对应的镜像

    docker build -t appium_cartierej_docker:latest .

  5. 运行 DisCartierEJ,它会去 STF 上寻找三台符合要求的设备返回。

  6. 然后将返回来的三个设备信息,根据设备名生产三个文件夹,并将每个设备的信息注入到相应文件夹下的 docker_compose.yml 中的环境变量中。

  7. 启动 up 每一个文件夹下的 docker_compose.yml,生成对应的容器,每个容器会先启动 appium 然后运行 case。

  8. 对应的日志会映射在本地,jenkins 根据日志,生成 report。

Demo 演示

下面我们运行一个实例来演示 DisCartierEJ 项目。

需求: 将一个 login 的 case 运行在 stf 所有可用的手机上。

前置条件: 先下载 Docker,并运行。

正式步骤:

  1. 编写一个 login case,所有的 case 要按照 CartierEJ 进行编写(非常简单)。

    只需要 clone 上面的代码即可。

    git clone https://github.com/haifengrundadi/CartierEJ.git

  2. 修改或者按着模板添加自己的功能,然后将代码上传到自己的 github 上。

    自己现在 github 上新建一个项目,名字叫 CartierEJ。
    其他如何 push 到 github 上,看 github 的提示。

  3. 从 github 上 git clone DisCartierEJ 这个项目。将 DisCartierEJ 中的 Dockerfile 中的获取 CartierEJ 的代码更改为步骤 2 的地址,并生成对应的镜像。

    ...
    #=======================================
    # pull code from git
    #=======================================
    RUN git clone https://github.com/haifengrundadi/CartierEJ.git
    ...

    生成对应的镜像(这个第一次比较慢,因为镜像比较大)

    docker build -t appium_cartierej_docker:latest .

  4. 修改 DisCartierEJ 的配置文件 config.py。见下

  5. 进入到 DisCartierEJ 的 core 的 generator.py

    python generator.py

config.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# the apk place in container
APK_NAME = "/apk_shell/xxx.apk"

# stf_url address
STF_URL = "http://xxx.xxx.xxx.xxx:7100/api/v1/devices"
"""
access token of stf
STF uses OAuth 2.0 for authentication. In order to use the API,
you will first need to generate an access token. Access tokens
can be easily generated from the STF UI. Just go to the Settings
tab and generate a new access token in Keys section.
Don't forget to save this token somewhere, you will not be able to see it again.
"""
TOKEN = "xxx"

STF_DELETE_URL = "http://xxx.xxx.xxx.xxx:7100/api/v1/user/devices/"

# some variables in desired_capablities
PLATFORM_NAME = 'Android'
NEW_COMMAND_TIMEOUT = 60

# come infomation needed by docker_compose.yml
APPIUM_CARTIEREJ_IMAGE = "appium_cartierej_docker:latest"
PORTS = 4723
APPIUM_CARTIEREJ_CMD = "bash /app_shell/app.sh"
APP_APK_VOLUMES = "/Users/red/xxx/:/apk_shell"

"""
Use device name as directory to save docker_compose.yml and app.sh
Need abs path
"""
DOCKER_COMPOSE_VOLUMES = "xxx/DisCartierEJ/resources/dockercomposes/"

# logs save place in local
LOCAL_LOG_DIR = "/Users/red/xxx/logs/"
APPIUM_CARTIEREJ_LOGS_VOLUMES = LOCAL_LOG_DIR + 'RANDOM:/opt/node/CartierEJ/logs'  # RANDOM为变量在生成的过程中替换

# case to run
CASE_NAME = "test_login.py"

结果

感受

一直坚持到现在,终于要先告一个段落,感谢一直坚持的自己。第一次把自己的代码安装规范一点的样式发出来。首先,发现自己的代码能力还是弱,很多知识不熟悉。第二,写文档对自己真是一个考验,也是一种成长和反思。第三,能心无杂物的去做一件事不容易。还有,把代码拿出来分享只是一个开始和阶段总结,希望大家一起讨论。

后续文章

开源项目:移动自动化测试框架 DisCartierEJ 之 CartierEJ 介绍


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