zoukankan      html  css  js  c++  java
  • Android自动化测试之Shell脚本一——模拟触屏事件

    摘自:http://guolin.guosfamily.com/2012/02/15/android-automated-test-by-shell-touch-event/

    Android自动化测试有很多方式,常见的包括 MonkeyRunner,Robotium,SL4A,Java Instrumentation,Shell脚本等(随机点击的Monkey测试太过低级不在此列)。这篇先介绍Shell脚本测试,我猜这可能是最不常 用的一种,但因为API很少,学习成本较低,如果对Shell较熟悉的同学就灰常合适:)

    了解手机上的设备

    手机上有很多输入设备,这些设备的编号每个手机都不同,因此我们需要首先了解这个手机上都有哪些输入设备,下面以我的NexusS为例:

    > adb shell cat /proc/bus/input/devices
    I: Bus=0000 Vendor=0000 Product=0000 Version=0000
    N: Name="mxt224_ts_input"
    P: Phys=
    S: Sysfs=/devices/virtual/input/input0
    U: Uniq=
    H: Handlers=event0
    B: EV=9
    B: ABS=2650000 0

    I: Bus=0000 Vendor=0000 Product=0000 Version=0000
    N: Name="gyro"
    P: Phys=
    S: Sysfs=/devices/virtual/input/input1
    U: Uniq=
    H: Handlers=event1
    B: EV=5
    B: REL=38

    I: Bus=0000 Vendor=0000 Product=0000 Version=0000
    N: Name="herring-keypad"
    P: Phys=
    S: Sysfs=/devices/virtual/input/input2
    U: Uniq=
    H: Handlers=event2 keychord
    B: EV=3
    B: KEY=1c0000 0 0 0

    I: Bus=0000 Vendor=0000 Product=0000 Version=0000
    N: Name="proximity"
    P: Phys=
    S: Sysfs=/devices/virtual/input/input3
    U: Uniq=
    H: Handlers=event3
    B: EV=9
    B: ABS=2000000

    I: Bus=0000 Vendor=0000 Product=0000 Version=0000
    N: Name="lightsensor-level"
    P: Phys=
    S: Sysfs=/devices/virtual/input/input4
    U: Uniq=
    H: Handlers=event4
    B: EV=9
    B: ABS=100 0

    I: Bus=0018 Vendor=0000 Product=0000 Version=0000
    N: Name="compass"
    P: Phys=
    S: Sysfs=/devices/virtual/input/input5
    U: Uniq=
    H: Handlers=event5
    B: EV=5
    B: REL=3ff
    以上高亮部分显示了这台手机上的6个输入设备,如下:

    设备名称说明HANDLER
    mxt224_ts_input屏幕触摸输入event0
    Gyro陀螺仪event1
    herring-keypad键盘event2
    proximity近距离感应器(脸颊感应)event3
    lightsensor-level光感应器event4
    compass定位仪event5
    注意:每台设备上的输入设备分布和名称都可能不一样

    选择一个合适的设备来进行我们的输入测试,对于大多数情况来说,一般只需要用到键盘和屏幕触摸输入,下面我们以屏幕触摸输入为例。将用到两个对应的命令:getevent和sendevent,顾名思义,一个是获取事件,另一个则是发送模拟事件。

    用getevent了解设备运作

    首先我们随便执行一条getevent来监听Handler event0(event0为屏幕事件):

    > adb shell getevent /dev/input/event0
    然后点击一下桌面上某一个app(使其进入),会看到类似以下内容:

    0003 0035 0000008b
    0003 0036 000002c0
    0003 0030 00000044
    0003 0032 00000004
    0003 0039 00000000
    0000 0002 00000000
    0000 0000 00000000
    0003 0035 0000008b
    0003 0036 000002c0
    0003 0030 00000000
    0003 0032 00000001
    0003 0039 00000000
    0000 0002 00000000
    0000 0000 00000000
    以上内容的格式为:[type] [code] [value]

    但这些type和code究竟是什么意思呢?输入以下指令

    > adb shell getevent -p /dev/input/event0
    add device 1: /dev/input/event0
    name: "mxt224_ts_input"
    events:
    SYN (0000): 0000 0003
    ABS (0003): 0030 value 0, min 0, max 255, fuzz 0 flat 0
    0032 value 0, min 0, max 30, fuzz 0 flat 0
    0035 value 0, min 0, max 1023, fuzz 0 flat 0
    0036 value 0, min 0, max 950, fuzz 0 flat 0
    0039 value 0, min 0, max 4, fuzz 0 flat 0
    这个依然有点晦涩,大意为:
    type类型可能出现两种,分别是 0000 代表 SYN,0003 代表 ABS
    ABS type下的code 类型可能出现若干种,包括 0030,0032,0035,0036,0039
    这五种code的意义可以参见 /frameworks/base/include/ui/EventHub.h

    #define ABS_MT_TOUCH_MAJOR 0x30 /* Major axis of touching ellipse */
    #define ABS_MT_TOUCH_MINOR 0x31 /* Minor axis (omit if circular) */
    #define ABS_MT_WIDTH_MAJOR 0x32 /* Major axis of approaching ellipse */
    #define ABS_MT_WIDTH_MINOR 0x33 /* Minor axis (omit if circular) */
    #define ABS_MT_ORIENTATION 0x34 /* Ellipse orientation */
    #define ABS_MT_POSITION_X 0x35 /* Center X ellipse position */
    #define ABS_MT_POSITION_Y 0x36 /* Center Y ellipse position */
    #define ABS_MT_TOOL_TYPE 0x37 /* Type of touching device (finger, pen, ...) */
    #define ABS_MT_BLOB_ID 0x38 /* Group a set of packets as a blob */
    #define ABS_MT_TRACKING_ID 0x39 /* Unique ID of initiated contact */
    #define ABS_MT_PRESSURE 0x3a /* Pressure on contact area */
    因此刚刚getevent获取到的内容大致可以做如下翻译:

    0003 0035 0000008b // x轴0x8b的位置
    0003 0036 000002c0 // y轴0x2c0的位置
    0003 0030 00000044 // 触摸椭圆的长轴为0x44
    0003 0032 00000004 // ??椭圆的长轴为0x4
    0003 0039 00000000 // Tracking ID为0
    0000 0002 00000000 // SYN
    0000 0000 00000000 // SYN
    ---- 昏割线 ----
    0003 0035 0000008b
    0003 0036 000002c0
    0003 0030 00000000 // 触摸椭圆的长轴为0(表示离开屏幕了)
    0003 0032 00000001
    0003 0039 00000000
    0000 0002 00000000
    0000 0000 00000000
    有了以上知识作为基础,我们就可以开始着手编写我们自己的自动化测试脚本了
    关于getevent的使用细节可以参见 Android官网上的一篇文章 ,不过里面写的东西基本是在扯蛋。

    使用sendevent模拟事件

    先看看sendevent的使用方法:

    > adb shell sendevent –h
    use: sendevent device type code value
    先做个简单的测试,我们回到桌面准备模拟一遍刚才点击的动作,如果成功的话会进入刚刚那个app。利用sendevent编写模拟事件脚本x.sh:

    #!/system/bin/sh
    sendevent /dev/input/event0 3 $((0x35)) $((0x8b))
    sendevent /dev/input/event0 3 $((0x36)) $((0x2c0))
    sendevent /dev/input/event0 3 $((0x30)) $((0x44))
    sendevent /dev/input/event0 3 $((0x32)) $((0x04))
    sendevent /dev/input/event0 3 $((0x39)) $((0x00))
    sendevent /dev/input/event0 0 $((0x02)) $((0x00))
    sendevent /dev/input/event0 0 $((0x00)) $((0x00))

    sendevent /dev/input/event0 3 $((0x35)) $((0x8b))
    sendevent /dev/input/event0 3 $((0x36)) $((0x2c0))
    sendevent /dev/input/event0 3 $((0x30)) $((0x00))
    sendevent /dev/input/event0 3 $((0x32)) $((0x04))
    sendevent /dev/input/event0 3 $((0x39)) $((0x00))
    sendevent /dev/input/event0 0 $((0x02)) $((0x00))
    sendevent /dev/input/event0 0 $((0x00)) $((0x00))
    以上高亮处表示,在同一个位置先点击后松开。现在执行

    > adb push x.sh /sdcard/
    > adb shell sh /sdcard/x.sh
    观察手机,发现之前的app被点击了

    这样我们成功的模拟了一个最简单的点击,如果想模拟其他的动作,可以尝试自己动手观察一下设备接收到的事件,再重复出来即可

    优化

    本来到这里应该已经完了,但作为一位懒惰的程序员,是无法接受平时写自动化测试脚本需要编写如此多如此重复的代码的,于是我总结了一下,抽象了一个小库,用于模拟屏幕上各种基础的动作

    #!/system/bin/sh
    # Script to execute automatical test.
    # By using: adb shell sendevent [device] [type] [code] [value]
    #
    # @author GuoLin

    # Click on a point
    click()
    {
        press $1 $2
        release $1 $2
    }

    # Long click on a point
    longclick()
    {
        press $1 $2
        press $1 $2
        sleep 1
    }

    # Fling from a point to another
    fling()
    {
        move $1 $2 $3 $4
        release $3 $4
    }

    # Drag and drop
    dad()
    {
        longclick $1 $2
        move $1 $2 $3 $4
        release $3 $4
    }

    # Move from a point to another
    move()
    {
        for i in 1 2 3 4;
        do
            x=$(( ($3 - $1) * $i / 3 + $1 ))
            y=$(( ($4 - $2) * $i / 3 + $2 ))
            press $x $y
        done;
    }

    # Press a point
    press()
    {
        sendevent $EVENT 3 $((0x35)) $1
        sendevent $EVENT 3 $((0x36)) $2
        sendevent $EVENT 3 $((0x30)) $((0x44))
        sendevent $EVENT 3 $((0x32)) $((0x04))
        sendevent $EVENT 3 $((0x39)) $((0x00))
        sendevent $EVENT 0 $((0x02)) $((0x00))
        sendevent $EVENT 0 $((0x00)) $((0x00))
    }

    # Release on a point
    release()
    {
        sendevent $EVENT 3 $((0x35)) $1
        sendevent $EVENT 3 $((0x36)) $2
        sendevent $EVENT 3 $((0x30)) $((0x00))
        sendevent $EVENT 3 $((0x32)) $((0x04))
        sendevent $EVENT 3 $((0x39)) $((0x00))
        sendevent $EVENT 0 $((0x02)) $((0x00))
        sendevent $EVENT 0 $((0x00)) $((0x00))
    }

    # Samples
    # Click on icon on cell 1,4
    #click $((0x8b)) $((0x2c0))
    # Scroll screen
    #fling $((0x8b)) $((0x2c0)) $((0x222)) $((0x2c0))
    # Drag and drop
    #dad $((0x8b)) $((0x2c0)) $((0x8b)) $((0x200))
    最底部的Samples例举了几种常用操作。
  • 相关阅读:
    工单相关函数
    ABAP 没有保存的长文本,如何取值
    小细节
    DEMO程序 排序
    ABAP 中的消息类型和处理方式
    那些 诡异的表格
    F4搜索帮助~出口函数
    使用XML的方式导出EXCEL
    更改销售订单某些字段和按钮 不可编辑
    ABAP-如何读取内表的字段名称
  • 原文地址:https://www.cnblogs.com/xin36933/p/3551251.html
Copyright © 2011-2022 走看看