• App 自动遍历工具初版 at 2016年02月19日

    #9 楼 @seveniruby 在这种遍历里面,是不是一定要有引导规则在里面

  • App 自动遍历工具初版 at 2016年02月19日

    思寒 什么时候开源能通过啊,想学习一下代码呢 .

  • App 自动遍历工具初版 at 2016年02月19日

    之前使用 Uiautomator 做了一个遍历的工具,最多执行到 3 层,再多逻辑就不好控制,

    研究一下你这个

  • TesterHome [性能专项] 系列 at 2016年02月18日

    已经报名

  • 这个问题 我之前遇到过一次 .

    我当时出现这个错误的原因是,滑动的坐标范围超出了对应控件的 bounds

  • #2 楼 @monkey 修改好了

  • @chenhengjie123 恒捷你好. 我想在招聘板块发布一条关于公司招聘测试开发的帖子,但没有权限,麻烦开通一下呢

  • STF 框架之 minicap 工具 at 2015年10月09日

    还需要注意一点:

    #!/usr/bin/env bash
    # Fail on error, verbose output
    set -exo pipefail
    # Build project
    ndk-build 1>&2
    # Figure out which ABI and SDK the device has
    abi=$(adb shell getprop ro.product.cpu.abi | tr -d '\r')
    sdk=$(adb shell getprop ro.build.version.sdk | tr -d '\r')
    rel=$(adb shell getprop ro.build.version.release | tr -d '\r')
    # PIE is only supported since SDK 16
    if (($sdk >= 16)); then
    bin=minicap
    else
    bin=minicap-nopie
    fi
    args=
    if [ "$1" = "autosize" ]; then
    set +o pipefail
    size=$(adb shell dumpsys window | grep -Eo 'init=\d+x\d+' | head -1 | cut -d= -f 2)
    if [ "$size" = "" ]; then
    w=$(adb shell dumpsys window | grep -Eo 'DisplayWidth=\d+' | head -1 | cut -d= -f 2)
    h=$(adb shell dumpsys window | grep -Eo 'DisplayHeight=\d+' | head -1 | cut -d= -f 2)
    size="${w}x${h}"
    fi
    args="-P $size@$size/0"
    set -o pipefail
    shift
    fi
    # Create a directory for our resources
    dir=/data/local/tmp/minicap-devel
    adb shell "mkdir $dir 2>/dev/null"
    # Upload the binary
    adb push libs/$abi/$bin $dir
    # Upload the shared library
    if [ -e jni/minicap-shared/aosp/libs/android-$rel/$abi/minicap.so ]; then
    adb push jni/minicap-shared/aosp/libs/android-$rel/$abi/minicap.so $dir
    else
    adb push jni/minicap-shared/aosp/libs/android-$sdk/$abi/minicap.so $dir
    fi
    # Run!
    adb shell LD_LIBRARY_PATH=$dir $dir/$bin $args "$@"
    # Clean up
    adb shell rm -r $dir
    

    在一些电脑上面

    size=$(adb shell dumpsys window | grep -Eo 'init=\d+x\d+' | head -1 | cut -d= -f 2)
    

    需要修改成

    size=$(adb shell dumpsys window | grep -Eo 'init=[0-9]+x[0-9]+' | head -1 | cut -d= -f 2)
    

    不然无法获取大 height 和 width

  • STF 框架之 minicap 工具 at 2015年10月09日

    按照 LZ 的文章步骤不能成功。

    很多手机直接 push 对应的 minicap 和 minicap.so 文件后,
    执行 adb shell LD_LIBRARY_PATH=/data/local/tmp /data/local/tmp/minicap -P 480x854@480x854/0 -t 命令会出现错误。

    错误信息 “/system/bin/sh: /data/local/tmp/minicap: can't execute: Permission denied”

    建议按照https://github.com/openstf/minicap 中的描述进行。

    总结一下直接的步骤:
    git clone https://github.com/openstf/minicap.git
    cd minicap
    git submodule init
    git submodule update
    ndk-build

    注意 ndk 的版本,android-ndk-r10e-linux-x86_64.bin

    由于直 git 的 minicap 项目依赖 libjpeg-turbo 模块 ,所以需要进行
    git submodule init
    git submodule update

    注意:直接下载项目和 git clone 项目是不一样的,所以要用 git clone 。否则 submodule 的操作不会成功。

  • 谷歌测试的一天 at 2015年09月28日

    哭着跪了 .

  • 为啥没有成都的测试开发工程师招聘

  • #3 楼 @chenhengjie123 嗯 . 需要验证切换用户前和切换用户后 一切设定和属性的正确性 .

  • #1 楼 @chenhengjie123

    Android L 加入了多用户的概念。

    至于 adb 重连和当前 Bootstrap 挂掉的原因,不是很清楚,毕竟属于 Android 开发的范畴了 。

    只是从 Appium 维度来解决这个问题 .

  • 我们和日本人说四川话

  • 看到这篇文档,说说我的理解.

    文件:

    ib\appium.js
    

    函数:

    Appium.prototype.invoke = function (cb)
    
    if (this.device.args.autoLaunch === false) {
       // if user has passed in desiredCaps.autoLaunch = false
       // meaning they will manage app install / launching
       if (typeof this.device.noLaunchSetup === "function") {
         this.device.noLaunchSetup(function (err) {
           if (err) return cb(err);
           cb(null, this.device);
         }.bind(this));
       } else {
         cb(null, this.device);
       }
     } else {
       // the normal case, where we launch the device for folks
       var onStart = function (err, sessionIdOverride) {
         if (sessionIdOverride) {
           this.sessionId = sessionIdOverride;
           logger.debug("Overriding session id with " +
                       JSON.stringify(sessionIdOverride));
         }
         if (err) return this.cleanupSession(err, cb);
         logger.debug("Device launched! Ready for commands");
         this.setCommandTimeout(this.desiredCapabilities.newCommandTimeout);
         cb(null, this.device);
       }.bind(this);
    
       this.device.start(onStart, _.once(this.cleanupSession.bind(this)));
     }
    

    这个函数会判断 autoLaunch 参数,直接将判断部分代码注释掉。只留下

    var onStart = function (err, sessionIdOverride) {
        if (sessionIdOverride) {
          this.sessionId = sessionIdOverride;
          logger.debug("Overriding session id with " +
          JSON.stringify(sessionIdOverride));
        }
        if (err) return this.cleanupSession(err, cb);
        logger.debug("Device launched! Ready for commands");
        this.setCommandTimeout(this.desiredCapabilities.newCommandTimeout);
        cb(null, this.device);
      }.bind(this);
    
      this.device.start(onStart, _.once(this.cleanupSession.bind(this)));
    

    在回放脚本时 不设置 app 的参数,autoLaunch = false,就可以不启动 APP,直接执行脚本中的动作。

  • #53 楼 @1056866402

    Usb 连接手机

    系统会自动在设备上面安装一个 STF Service

  • STF 前提依赖都安装好了

    执行 sudo npm install -g stf 不成功

    错误信息:
    gyp WARN EACCES user "root" does not have permission to access the dev dir "/home/zhaojiajun/.node-gyp/4.0.0"
    gyp WARN EACCES attempting to reinstall using temporary dev dir "/usr/local/lib/node_modules/stf/node_modules/ws/node_modules/utf-8-validate/.node-gyp"

    请问这是什么原因导致的呢

  • #2 楼 @zsx10110

    每个点击都写一次文件,是不是有点耗时,占用资源了。

    可以将点击后生成的脚本直接放在 StringBuilder 中,这样最后再直接生成。或则将每行的脚本放在一个数据结构中,最后保存脚本的时候,再写入文件。

  • 准确的来说 Appium 支持在父控件中查找子控件。

    在 selenium 的 webelement 类中你可以查找到对应的内容:

    def find_element_by_class_name(self, name):
            """Finds element within this element's children by class name.
    
            :Args:
                - name - class name to search for.
            """
            return self.find_element(by=By.CLASS_NAME, value=name)
    

    在 Appium python clinet 中的 WebElement 就是继承 Selenum 的 WebElement 扩展了在 UiAutomator 中的 accessibility id 以及直接使用 Uiautomator 的语法规则。

    class WebElement(SeleniumWebElement):
        def find_element_by_ios_uiautomation(self, uia_string):
            """Finds an element by uiautomation in iOS.
    
            :Args:
             - uia_string - The element name in the iOS UIAutomation library
    
            :Usage:
                driver.find_element_by_ios_uiautomation('.elements()[1].cells()[2]')
            """
            return self.find_element(by=By.IOS_UIAUTOMATION, value=uia_string)
    
        def find_elements_by_ios_uiautomation(self, uia_string):
            """Finds elements by uiautomation in iOS.
    
            :Args:
             - uia_string - The element name in the iOS UIAutomation library
    
            :Usage:
                driver.find_elements_by_ios_uiautomation('.elements()[1].cells()[2]')
            """
            return self.find_elements(by=By.IOS_UIAUTOMATION, value=uia_string)
    
        def find_element_by_android_uiautomator(self, uia_string):
            """Finds element by uiautomator in Android.
    
            :Args:
             - uia_string - The element name in the Android UIAutomator library
    
            :Usage:
                driver.find_element_by_android_uiautomator('.elements()[1].cells()[2]')
            """
            return self.find_element(by=By.ANDROID_UIAUTOMATOR, value=uia_string)
    
        def find_elements_by_android_uiautomator(self, uia_string):
            """Finds elements by uiautomator in Android.
    
            :Args:
             - uia_string - The element name in the Android UIAutomator library
    
            :Usage:
                driver.find_elements_by_android_uiautomator('.elements()[1].cells()[2]')
            """
            return self.find_elements(by=By.ANDROID_UIAUTOMATOR, value=uia_string)
    
        def find_element_by_accessibility_id(self, id):
            """Finds an element by accessibility id.
    
            :Args:
             - id - a string corresponding to a recursive element search using the
             Id/Name that the native Accessibility options utilize
    
            :Usage:
                driver.find_element_by_accessibility_id()
            """
            return self.find_element(by=By.ACCESSIBILITY_ID, value=id)
    
        def find_elements_by_accessibility_id(self, id):
            """Finds elements by accessibility id.
    
            :Args:
             - id - a string corresponding to a recursive element search using the
             Id/Name that the native Accessibility options utilize
    
            :Usage:
                driver.find_elements_by_accessibility_id()
            """
            return self.find_elements(by=By.ACCESSIBILITY_ID, value=id)
    
        def set_text(self, keys=''):
            """Sends text to the element. Previous text is removed.
            Android only.
    
            :Args:
             - keys - the text to be sent to the element.
    
            :Usage:
                element.set_text('some text')
            """
            data = {
                'elementId': self._id,
                'value': [keys]
            }
            self._execute(Command.REPLACE_KEYS, data)
            return self
    
  • Appium 多设备连接执行问题 at 2015年07月22日

    uid 区分设备 id

    和对应的 Server port 和 Bootstrap port . 就可以解决 .

  • Appium 多设备连接执行问题 at 2015年07月22日

    问题已经解决了 。

  • 检查
    python-client-master\appium\webdriver\webdriver.py 中是否还有这个方法.

  • #5 楼 @anikikun

    启动慢是一回事,脚本没单个动作慢是另一回事。

    脚本单个动作慢 可能需要看看具体实现

    def _get_opts(self, element, x, y, duration = None):
            opts = {}
            if element is not None:
                opts['element'] = element.id
    
            # it makes no sense to have x but no y, or vice versa.
            if x is None or y is None:
                x, y = None, None
            opts['x'] = x
            opts['y'] = y
    
            if duration is not None:
                opts['duration'] = duration
    
            return opts
    

    得看看默认 duration 是不是为 None,有些默认 duration 可能设置有基础时间

  • appium 自动化测试 求资料 at 2015年04月22日

    最好的资料就是源代码

    源代码中直接有 doc~