自动化工具 pyminitouch - 用 python 驱动 minitouch

williamfzc · 2018年12月23日 · 最后由 williamfzc 回复于 2021年02月04日 · 1854 次阅读

pyminitouch

项目 github

一开始使用 minitouch 纯粹是为了适应一些特殊场景的需要,例如高效的设备操作、模拟硬件操作等等。(同时也为了解决这个问题 https://testerhome.com/topics/17247

但 minitouch 的使用体验实在是有点太差了,每次都要重复给手机安装指定版本的 minitouch、建立 socket、然后再编辑可读性极差的操作命令(形如'd 0 500 500 50\nc\nd 1 500 600 50\nw 5000\nc\nu 0\nu 1\nc\n'),当遇上多手机操作的时候更是抓瞎。

所以,开发了这个 minitouch 的 python 操作库,用于简化 minitouch 的使用流程。虽然 minitouch 的用途还是比较局限,但是想着可能有人会需要这个东西,就把它共享在这里吧~

目标

该项目将对 minitouch 进行封装,致力于降低使用成本,使这个库能够更好的被利用起来。

TL;DR

以前

  • 检查设备 CPU 类型
  • 下载指定版本的 minitouch(或者自己 build)
  • 把它 push 到手机上,授权,运行它
  • 创建 socket,连接到它
  • 通过 socket 传递信息,然而你的信息看起来是这样的:
    • d 0 150 150 50\nc\nu 0\nc\n
    • 可读性较低

是个非常繁琐的流程。

现在

from pyminitouch import safe_device


_DEVICE_ID = '123456F'
device = MNTDevice(_DEVICE_ID)

# single-tap
device.tap([(400, 600)])
# multi-tap
device.tap([(400, 400), (600, 600)])
# set the pressure, default == 100
device.tap([(400, 600)], pressure=50)

# 可以直接用简洁的API调用minitouch提供的强大功能!

更多使用方式见 demo.py

安装

请使用 python3

pip install pyminitouch

实现原理

其实跟 TLDR 提到的"以前的"流程是一样的。可以到项目主页看看源码 https://github.com/williamfzc/pyminitouch

意义

minitouch 是 openstf 基于 ndk + android 开发的用于模拟人类点击行为的操作库。这个库以高稳定性、反应快著称,比起 adb 操作与 uiautomator 都要更灵敏,被广泛用于 android 设备的精细操作。

然而,因为其使用与安装的方式都较为繁琐,且无法定位到元素,使得它在自动化的应用领域上远远比不上 uiautomator。

但他的实现机制与其他模拟方式不同,能够真正模拟物理点击的效果(uiautomator 属于软件层面上的模拟),更加接近真实点击的效果。举个例子,打开 开发者模式 - 显示点击位置,同类产品在模拟点击时不会有"小圆圈",而 minitouch 有,表现与真实人手点击一致。

bug & 建议

欢迎在评论或者 github 提 issue 给我 :)

共收到 26 条回复 时间 点赞

使用体验不差呀

先收藏,楼主加油

codeskyblue 回复

😀 主要感觉本来的话 怎么拼接字符串 通信 装指定版本还是挺麻烦的 当然它本身功能还是很好用的

有点好奇,楼主为什么一定要看到那个触摸的小圆点呢?

主要是希望图像识别可以识别到这个点,以支撑其他的工具:https://testerhome.com/topics/16063
没有该点的话 用户操作暂时无法获取到 所以比较麻烦

williamfzc 回复

minitouch 本来就是一个底层工具,都是用程序来跟它交互的

codeskyblue 回复

是的.. 不过这个东西主要也是为了支撑其他工具用 作为中间件存在吧 不然一旦要用 minitouch 都要重新搞一个连接层麻烦死了😹

hi man,我这边执行发现通过 socket 发送命令后不一定会进行点击操作,需要多次才会执行操作,这是什么原因

nennhui 回复

看看代码..?

williamfzc 回复
import socket,struct
class minitouch():
    BUFFER_SIZE = 4096
    def __init__(self, host, port):
        self.host = host
        self.port = port
        self.__socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.__socket.connect((self.host, self.port))

    def click(self,x,y):
        f="d 0 {} {} 50\nc\nu 0\nc\n  ".format( x, y)
        f = (f.encode('utf-8'))
        self.__socket.send(f)

if '__main__' == __name__:

    mc = minitouch('localhost', 1111)
    mc.click(100,444)   
}

我就简单的用 socket 发送了执行命令,但是运行一次不一定会在手机上执行命令,可能需要运行好几次。之前以为是延迟,但是试了很多次还是一样的情况。方便

nennhui 回复

贴代码最好用 ``` 括起来,不然看起来还是很乱😂

minitouch 在建立连接完成之后会打出一些版本信息之类的东西(你可以手动启动 minitouch 看看),在 socket 建立之后应该先把这些信息给去掉或者做特定处理,可以参考pyminitouch/connection.py里的实现。我感觉这个比较符合你说的运行好几次才会执行命令的情况。

您好,使用 pyminitouch 报错,可以帮忙看看吗?:
代码如下:

from pyminitouch import safe_connection, safe_device, MNTDevice, CommandBuilder
_DEVICE_ID = "FA69K0310399"
device = MNTDevice(_DEVICE_ID)
device.tap([(400, 600)])

zailushang 回复

重启下 adb 试试,这种应该是上一次执行 socket 没关闭引起的问题。在使用后要:

# stop minitouch
device.stop()
williamfzc 回复

重启也不行,我手机上安装过 airtest,跟这个有关系吗?

zailushang 回复

刚试了下,跟 airtest 倒是还好。
uiautomator2 的话之前有人说过这个问题,确实会存在冲突的情况但是一般重启 adb 就会 ok 了。

williamfzc 回复

好的,多谢,我再试试
再多请教一个问题,用 minitouch 点击的话,平均操作耗时多少啊?我直接用 adb 操作点击,耗时 300~500ms

zailushang 回复

具体步长没测过,不过这东西本来就被设计用于实时性很强的场景,效率方面我还没遇到什么问题
example/draw_heart.py 这个例子是在屏幕上画一个❤,瞬间就完成了,可以试试看

仅楼主可见
williamfzc 回复

增加了一行可以了

zailushang 回复

明白了,这个之前有人说过,不过我这边一直没复现,还挺奇怪的。
https://github.com/williamfzc/pyminitouch/issues/8

我找个时间再看看好了

williamfzc 回复

好的,辛苦

minitouch 有输入字符的接口吗?

terencejgwang 回复

如果你说的是类似 adb shell input text ,没有的。minitouch 都是纯 ui 层面的操作。

大神,我在跑 pyminitouch 的 demo 的 遇到很多报错

邱正芳 回复
  • 日志不完整
  • 统一转 github issue 管理把
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册