Skip to content

danbao/AirtestX

 
 

Repository files navigation

AirtestX (中文版)

Build Status Documentation Status PyPI PyPI PyPI

该项目是为了让手机应用的一些常规测试可以自动化起来,让测试人员摆脱那些枯燥的重复性工作。 基于OpenCV的图像识别技术,有点类似于SikuliX(这东西挺好用的,只是没说要支持手机端)

Features

  1. 完全的黑盒测试框架,无需知道项目代码,非侵入式
  2. 可是很好的支持安卓手机的测试,包括安卓模拟器
  3. 支持Windows应用的测试
  4. 对于游戏测试,可以使用图像缩放的方法适应不同分辨率的手机

历史起源

改版自一个老项目 https://github.com/netease/airtest airtest已经有人用,但是这次重构,估计好多api都会变了。最好的办法还是重建一个项目比较好,感谢https://github.com/pactera给起的名字 AirtestX

另外airtest中的很多代码不符合python编码规范, 冗余的功能夹杂在里面,很不好维护。 为了能够重现该软件昔日的光芒,是时候擦亮代码,重出江湖了。

与原版主要变化

  • 简化安装方式,只需要安装opencv以及通过pip安装atx(airtestX的简称)无其他依赖
  • 支持原生UI元素的查找和点击
  • 截图方式重原有缓慢的adb截图,改成默认uiautomator截图,可选minicap截图(1080x1920手机截图平均耗时0.2s)
  • 优化图像的自动缩放算法,以便同样的脚本可以适应不同的机器
  • 支持Watch用法,可持续监控界面,当某个元素出现时执行特定操作
  • 截图客户端从网页服务器变成了python-Tkinter写的客户端 使用python -matx gui启动
  • 支持dir(dev) 查看元素已有的方法(-_-! 之前代码写的不好,并不支持)
  • 更稳定的依赖库控制,与travis持续集成,可在代码更新后自动发布到pypi
  • 移除性能监控功能,暂时移除iOS支持
  • 图像匹配默认使用模版匹配,将SIFT匹配改为可选

依赖

  1. python2.7
  2. opencv2.4, numpy
  3. Android4.1+

安装

  1. 首先安装opencv(>=2.4 && <3.0)到你的电脑上

    windows推荐直接通过pip安装, 根据你是win32还是amd64选择合适的版本,如果pip安装不上,就需要把相应的numpy和opencv下载下来。然后在本地安装 备用下载地址 安装方法很简单,例如 pip install np.whl, pip最好版本高一点(>=8.1.0),避免出错

    # For Win32
    pip install http://goandroid.qiniudn.com/opencv_python-2.4.12-cp27-none-win32.whl
    pip install http://goandroid.qiniudn.com/numpy-1.10.4.mkl-cp27-none-win32.whl
    # For AMD64
    pip install http://goandroid.qiniucdn.com/opencv_python-2.4.12-cp27-none-win_amd64.whl
    pip install http://goandroid.qiniucdn.com/numpy-1.10.4.mkl-cp27-none-win_amd64.whl
    

    如果是Macbook,安装方法要比想象中的简单,然而耗时也比想象中的要长, 先安装brew, 之后

    brew install python pillow opencv
    
  2. 安装airtest

    为了编码的时候能少敲一点字母, pip中软件包的名字简化成了 atx

    pip install --upgrade atx
    

    For the develop version, (maybe not stable), Sync with github master code

    pip install --upgrade --pre atx
    

    有的时候Pypi会有点抽风, 从源码安装也是可行的

    pip install -U git+https://github.com/codeskyblue/AirtestX.git
    
  3. 安装ADB (Android Debug Bridge)

    下载adb安装到电脑上,推荐下载地址 http://adbshell.com/

快速入门

  1. 连接一台安卓手机 (4.1+)

    打开windows命令行,执行 adb devices, 请确保看到类似输出, 没有其他的错误

    $ adb devices
    List of devices attached
    EP7333W7XB      device
  2. 创建一个python文件 test.py, 内容如下

    # coding: utf-8
    import atx
    
    d = atx.connect() # 如果多个手机连接电脑,则需要填入对应的设备号
    d.screenshot('screen.png') # 截图

    运行 python test.py

  3. 截图

    命令行运行 python -matx gui, 鼠标左键拖拽选择一个按钮或者图标, 按下Save Cropped截图保存推出. (按下Refresh可以重新刷新屏幕)

    tkide

    PS: 这里其实有个好的IDE截图的最好了,现在是用Tkinter做的,比较简洁,但是可以跨平台,效果也还可以

    截图后的文件另存为 button.png, test.py 最后增加一行 d.click_image('button.png')

    重新运行 python test.py, 此时差不多可以看到代码可以点击那个按钮了

  4. 更多

    可以使用的接口还有很多,请接着往下看

使用举例

AirtestX毕竟是一个python库,给出代码的例子可能更好理解一些

接口可以参考sphinx自动生成文档 Documentation on ReadTheDocs 文档等下在看,先看一些例子

  • 初始化设备的连接

     import atx
    
     d = atx.connect()
  • App的起停

     package_name = 'com.example.game'
    
     d.stop_app(package_name)
     # d.stop_app(package_name, clear=True) # stop and remove app data
     d.start_app(package_name)
  • 执行Shell命令

     d.adb_cmd(['pull', '/data/local/tmp/hi.txt'])
     d.adb_shell(['uptime'])
     print d.forward(10080) # forward device port to localhost
     # Expect (host, port)
     print d.wlan_ip # 获取手机的Wlan IP
  • 图片查找与点击

     # find image position
     if d.exists('button.png'): # 判断截图是否在屏幕中出现
     	print 'founded'
    
     # take screenshot
     d.screenshot('screen.png') # 保存屏幕截图
    
     # click position
     d.click(50, 100) # 模拟点击 x, y
     
     # click offset image
     d.click_image(atx.Pattern('button.png', offset=(100, 20))) # 带有偏移量的点击
    
     # 指定截图时手机的分辨率是 1920x1080 以便脚本运行在其他分辨率的手机上时可以自动适应
     d.click_image(atx.Pattern('button.png', rsl=(1080, 1920))) 
    
     # if image not show in 10s, ImageNotFoundError will raised
     try:
     	d.click_image('button.png', timeout=10.0)
     except atx.ImageNotFoundError:
     	print('Image not found')
    
     # 在特定的区域内查找匹配的图像(IDE暂时还不支持如此高级的操作)
     nd = d.region(atx.Bounds(50, 50, 180, 300))
     print nd.match('folder.png')
  • 原生UI操作

    如何点击UI元素请直接看 https://github.com/codeskyblue/airtest-uiautomator 里面的API是直接通过继承的方式支持的。

     # click by UI component
     d(text='Enter').click()
  • 常用配置

     # 配置截图图片的手机分辨率
     d.resolution = (1920, 1080)
     print d.resolution
     # expect output: (1080, 1920) 实际获取到的值会把小的放在前面
    
     # this is default (first check minicap and then check uiautomator)
     d.screenshot_method = atx.SCREENSHOT_METHOD_AUTO # 默认
     # d.screenshot_method = atx.SCREENSHOT_METHOD_UIAUTOMATOR # 可选
     # d.screenshot_method = atx.SCREENSHOT_METHOD_MINICAP # 可选
    
     d.image_match_method = atx.IMAGE_MATCH_METHOD_TMPL # 模版匹配, 默认
     # d.image_match_method = atx.IMAGE_MATCH_METHOD_SIFT # 特征点匹配, 可选
    
     # d.image_match_threshold = 0.8 # 默认(模版匹配相似度)
    
     d.rotation = None # default auto detect, 这个配置一下比较好,自动识别有时候识别不出来
     # 0: home key bottom(normal)
     # 1: home key right
     # 2: home key top
     # 3: home key left
    
     # 图片路径查找(实验性功能)
     d.image_path = ['.'] # 默认
     
     # 主要用在希望代码和图片放在不同目录的情况, 如代码结构
     # /--
     #   |-- test.py
     #   |-- images/
     #          |- photo1.png
     #          `- photo2.png
     #
     
     # test.py 中的关键性代码
     d.image_path = ['.', 'images']
     d.click_image('photo1.png')
     d.click_image('photo2.png')
  • 监控事件

     # watcher, trigger when screenshot is called
     def foo(event):
     	print 'It happens', event
     	d.click(*event.pos)
    
     timeout = 50 # 50s
     with d.watch('enter game', timeout) as w:
     	w.on('enter-game').click()
     	w.on('inside.png').quit()
     	w.on(text='Login').quit() # UI Component
     	w.on('outside.png').do(foo)

配置项

一般来说用默认的就好了,大部分都不需要改

接口说明

其实看ReadTheDocs上的文档更好一点,这里也不打算列出来多少接口 Documentation on ReadTheDocs

连接设备

connect(udid, **kwargs)

对于安卓设备常见连接方法

connect() # only one device
connect(None)
connect(None, host='127.0.0.1', port=5037)
connect('EFSXA124') # specify serialno

connect返回一个Device对象, 该对象下有很多方法可以用,使用举例

d = atx.connect(None)
d.screenshot('screen.png')

Device下的方法

截图

screenshot(filename)

可以自动识别屏幕的旋转

Parameters

Name | Type   | Description

---------|--------|------------ filename | string | Optional 保存的文件名

Returns

PIL.Image

坐标点击

click(x, y)

image support string or pillow image

Parameters

Name Type Description
x, y int 坐标值

Example

click(20, 30)

其他接口

批量运行脚本

推荐用unittest, 它是python自身的一个测试框架(其他出色的也有nose, pytest) 等等,看个人喜好

```py
# coding: utf-8

import unittest
import atx

d = atx.connect()

class SimpleTestCase(unittest.TestCase):
    def setUp(self):
        name = 'com.netease.txx'
        d.stop_app(name).start_app(name)

    def test_login(self):
        d.click_image("confirm.png")
        d.click_image("enter-game.png")
        with d.watch('Enter game', 20) as w:
            w.on("user.png").quit()


if __name__ == '__main__':
    unittest.main()
```

FAQ

  1. 如果连接远程机器上的安卓设备

    远程机器上使用如下命令启动命令

    adb kill-server
    adb -P 5037 -a fork-server server
    

    连接时指定远程机器的IP和端口号就好了

  2. 如何一个脚本可以适应不同的机器(针对于手机游戏)

    市面上大部分的手机都是 16:9 还有一部分是 4:3,5:3,8:5 其他比例的似乎了了。而游戏中元素的大小,在屏幕变化的时候,也会等比例的去缩放。16:9到4:3的缩放比例似乎也有规律可循,暂时不研究啦。

    16:9的的常见分辨率

    • 540x960
    • 720x1280
    • 1080x1920
    • 1440x2560

    4:3

    • 1536x2048

    5:3

    • 1152x1920
    • 1080x1800

    8:5

    • 800x1280
    • 1200x1920
    • 1600x2560

    所以通常只需要找个分辨率高点的设备,然后截个图。同样宽高比的手机就可以一次拿下。

    d.resolution = (1080, 1920)
    

    设置完后,当遇到其他分辨率的手机,就会自动去缩放。因为AirtestX主要针对游戏用户,横屏的时候,缩放是根据Y轴缩放的,竖排则根据X轴。可能有点抽象,理解不了也没关系

  3. 是否可以在模拟器上运行自动测试

    测试后,发现是可以的。我直接用了当前市场上最流行的海马玩 版本0.9.0 Beta 安装完之后使用 adb connect 127.0.0.1:26944 连接上,之后的操作就跟普通的手机一样了。注: 根据海马玩版本的不同,端口可能也不一定一样

    海马玩监听的端口是本机的26944,如果需要测试脚本运行在远程,用tcp转发到0.0.0.0就好了。方法有很多,可以用自带的程序 python -matx tcpproxy 或者直接参考目录下的 scripts/simple-tcp-proxy.py 用代码实现

  4. minicap是什么, 如何安装?

    minicap是openstf开源项目中的一个子项目,用于手机快速的截图. 连接手机到电脑上之后,简单的安装方法 python -matx minicap 注意:请不要在模拟器上尝试

代码导读

connect 函数负责根据平台返回相应的类(AndroidDevice or IOSDevice)

图像识别依赖于另一个库 aircv, 虽然这个库还不怎么稳定,也还凑合能用吧

每个平台相关的库都放到了 目录 atx/device下,公用的方法在atx/device/device_mixin.py里实现。

相关的项目

  1. 基于opencv的图像识别库 https://github.com/netease/aircv

  2. 感谢作者 https://github.com/xiaocong 提供的uiautomator的python封装,相关项目已经fork到了

  3. SikuliX http://sikulix-2014.readthedocs.org/en/latest/index.html

  4. Blockly https://github.com/codeskyblue/blockly

Contribute

如何才能让软件变的更好,这其中也一定需要你的参与才行,发现问题去在github提个issue, 一定会有相应的开发人员看到并处理的。文档有错误的话,直接提Issue,或者提PR都可以。 由于我平常使用该项目的概率并不怎么高,所有不少问题即使存在我也不会发现,请养成看到问题提Issue的习惯,所有的Issue我都会去处理的,即使当时处理不了,等技术成熟了,我还是会处理。但是如果不提交Issue,说不定我真的会忘掉。

BTW: 有开发能力的也可以先跟开发者讨论下想贡献的内容,并提相应的PR由开发人员审核。

网易内部用户暂时请直接联系 hzsunshx

License

This project is under the MIT License. See the LICENSE file for the full license text.

About

Make mobile test automated. Based on opencv.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • Python 83.1%
  • Go 6.6%
  • HTML 5.0%
  • JavaScript 3.9%
  • Shell 1.0%
  • Makefile 0.2%
  • Other 0.2%