• 对于你目前的需求,这个应该就够了。没必要纠结写得好不好,能用、好用最重要。

  • 这个开源团队搭源码环境的时候很多人遇到过,原因是 appium 一个依赖包(你图中的是 utf-8-validate)在 windows 上运行需要使用 VCBuild.exe 来编译。
    如果只是使用的话,直接用封装成 exe 版本的 appium 最方便,而且还能很方便地切换不同 appium 版本。
    这个严格来说也不算 appium 的问题,它只是依赖了一个对 windows 不大友好的包而已。。。

  • 有个小问题,你滑动的坐标是centreY +- 30,这里的 30 应该可以通过计算得到(比如通过控件高度来计算滑动一个元素所需要滑动的距离),而不需要作为固定值写在方法里吧?
    当然,如果你只有这个控件需要用到这个方法,写在里面问题应该也不大。

  • Python behave in BDD at 2015年03月26日

    #2 楼 @lucasluo 不客气。我也通过帖子学到不少。

  • Python behave in BDD at 2015年03月26日

    贴个文中用到的第三方库链接:http://pythonhosted.org/behave/
    看完后发现没找到里面用的库的链接(我觉得这种规范性的东西应该会有第三方库实现),然后搜了一下,应该就是文中用的那个库了。

  • appium 入门建议先把这里的文档看一下:
    https://github.com/testerhome/appium/tree/master/docs/cn
    看完后你就对 appium 有一定了解了。
    至于脚本的语法,你可以先学学 webdriver api,网上有很多教程的。

    不懂的地方先看官方文档,这样效率最高。

  • 从 log 看到是在这个位置开始出错的:

    info: [IOS_SYSLOG_ROW ] Mar 26 11:50:55 A050002673-iPhone6 ReportCrash[2216] <Notice>: MS:Notice: Injecting: (null) ReportCrash
    
    info: [IOS_SYSLOG_ROW ] Mar 26 11:50:55 A050002673-iPhone6 ReportCrash[2216] <Error>: task_set_exception_ports(B07, 400, F03, 0, 0) failed with error (4: (os/kern) invalid argument)
    info: [IOS_SYSLOG_ROW ] Mar 26 11:50:55 A050002673-iPhone6 ReportCrash[2216] <Notice>: ReportCrash acting against PID 2205
    
    info: [IOS_SYSLOG_ROW ] Mar 26 11:50:55 A050002673-iPhone6 diagnosticd[705] <Error>: error evaluating process info - pid: 2205, punique: 2205
    
    info: [IOS_SYSLOG_ROW ] Mar 26 11:50:55 A050002673-iPhone6 ReportCrash[2216] <Notice>: Formulating crash report for process ScriptAgent[2205]
    
    info: [IOS_SYSLOG_ROW ] Mar 26 11:50:55 A050002673-iPhone6 backboardd[74] <Notice>: ALS: SetDisplayFactor: factor=1.0000
    
    info: [debug] [INST STDERR] 2015-03-26 11:50:53.978 instruments[37140:6307] Automation Instrument ran into an exception while trying to run the script. UIAScriptAgentSignaledException
    

    Automation Instrument ran into an exception while trying to run the script. UIAScriptAgentSignaledException搜索,在 github 找到个类似的 issue:
    https://github.com/appium/appium/issues/3687
    你是不是没有打开开发者选项的Enable UI Automation?(我不大记得中文叫什么了)?

  • #18 楼 @uncle_mm 能解决就好!其实我之前也只知道>>><这种重定向第一次玩。。。

  • sample code 在另一个地方:https://github.com/appium/sample-code
    建议你先读文档,有个大概了解(特别是可能出现的问题和解决方案),再去跑 sample code。
    否则直接跑 sample code 你会遇到很多问题不知道怎么解决。

  • 你说得对,刚刚试了一下,就算 adb 断开了,monkey 还是会继续执行。应该它本来就是 daemon 模式执行的吧。

    另外关于你之前提到的adb shell < cmd.txt,试验了一下,确实可以用。
    给个简单例子你参考:

    test.bat

    adb shell < cmd.sh
    pause
    

    cmd.sh

    monkey 10 > /sdcard/monkey.log
    exit
    
    两个文件都放在电脑里的同一文件夹,记得cmd.sh最后一行是空行,否则会停在出现了exit命令但没执行的地方。
    cmd.sh里面就能像写shell脚本那样任意写命令了。
    
  • #7 楼 @uncle_mm 有一点不是很明白,你说 adb 连接不稳定,那么如果 adb 断开,你通过 adb 连到手机 shell 的连接也会断开啊。断开后 monkey 就会自动停止啦(除非另外搞个 daemon 来跑 monkey)。那么你的日志放电脑和放手机有啥区别?

  • #38 楼 @james88233 我又升级了。。。你看完文档后自己参考 sample code 写一写简单的脚本,你对怎么用 Appium 应该就大致了解了。
    webdriver 已经封装好很多方法,你直接拿来用就好了,方法名称和用法还是挺直观的。

  • @uncle_mm 你的 cmd.txt 里面写的是什么?
    另外,你要的是什么报告,需要先进入 shell 命令行才能得到?

  • #36 楼 @james88233 额,我这是个比喻。。。这个 “server”(实际上不一定是个 server)没有执行命令时和你平时把一个应用放在后台的压力差不多,不会把手机拖慢的。而且你没有运行 appium 脚本时,这个 server 什么都不会做。
    另外,自动化测试有分很多种,Appium 主要是 UI 自动化。而压力测试是另一种自动化,性能测试又是另一种自动化。UI 自动化的目的主要是保证功能的正确性(在 UI 层面),至于是否完全模拟用户操作取决于你的 “完全” 定义是什么。如果说和用户实际操作顺序/动作基本一样,这个是没问题的,如果你说连输入方式都一样(例如输入中文还能通过拼音 + 选字/手写来输入)这个不行。
    自动化不是万能的,至少不能完全替代手工测试。但用在适当的地方会很有用(例如需要重复执行的、基本不会再变化用例,如回归测试的用例)。

  • #2 楼 @monkey 他的意思应该是先通过 adb shell 进入手机的 shell,然后在这个 shell 里面调用 monkey 命令。他想把整个过程写成一个 bat 文件,双击就能执行。

  • 个人建议你看看 Appium 的一些文档:
    https://github.com/testerhome/appium/tree/master/docs/cn/
    这些文档都看完的话,你对 appium 基本有个整体了解了。

  • #33 楼 @james88233 额,先澄清一下,我不是老师,我也在学习中。。。
    Appium 的运行原理是通过 appium server 操作 Android UIAutomator(Android 4.3 以上)/Selendroid(Android 4.3 以下,2.3 以上)/UIAutomation(iOS),这些操作通过网络通讯进行控制(你可以理解为在手机上另外开了一个小的 server),而不是简单的翻译成其他其他语言的脚本。
    原封不动地跑起来这个可能性不大。因为界面是不可能完全一模一样的。即使你看起来是一模一样,但页面实际布局方式、控件的 id 等基本不会一样,所以元素的定位方式会不一样。但如果把元素定位分离出来做成独立的存储库(如 excel),脚本可重用性会高很多。
    简单的说,一个元素的 click 方法在 Android 和 iOS 都能用,效果都一样。不同的是你查找元素的方法有很大可能会不一样(毕竟源码不可能一样)。

    单种语言实现跨平台操作这个听起来很高大上,实际上就是通过网络通讯实现嘛。网络通讯用来发命令(语言无关,如使用 json 格式),接收方(Android 用 Java,iOS 用类 javascript)只要能识别这个命令并执行操作就好了。

  • #29 楼 @weamylady 额,我现在也才刚申请到 mac,刚开始用。不过研究 appium 的时候跑过一下它自带的用例,就以我的了解给些参考吧:

    1、你指的 绑定 UDID 是指绑定 UDID 到开发者账号吗?如果是,这个是一定要的。真机调试必须绑定 UDID(除非你是 299 美刀一年的那种高级开发者账号,有 in-house 分发功能),否则你的 app 只能在模拟器上跑。至于 in-house 分发的能否通过 appium 来做自动化测试,我没试过,所以不清楚。

    2、优点是遵循 webdriver 规范,可以使用各种语言的 client 编写,支持真机、webview,而且基本不需要改动应用代码。缺点的话环境配置可能算一个(要装的东西有点多,不过都是 iOS 开发必装的),不过因为没怎么实际用过使用其它方式做 ios 自动化测试的框架(如 calabash, monkeyTalk),所以也比较不了太多。

    3、执行效率和人工点击不会相差太大,某些时候甚至会慢一点。不要想着会有 selenium+web 那样飞一样的速度,因为移动设备的 UI 有很多切换动画,即使做到这么快的速度你也会因为动画不得不放慢速度。不过优势是重复执行不需要花费人力。

    4、没有代码基础的话难度相对于 MonkeyTalk 比较大(有录制和没录制的质的区别)。其实 Appium 的最大优势是遵循 webdriver 规范和基本不需要改动被测应用。如果这两点你都不需要,那么最容易产生产出的应该是 MonkeyTalk。

  • #9 楼 @mildshark 我昨天看了 appium 源码,好像它会把 press->wait->moveTo->release 转化才 swipe(必须按照前面的顺序),然后 swipe 才是你实际需要用的动作。具体情况我今晚再看看吧。
    另外,你确定你移动的速度和范围足够了?可以打开触控指示看看触控点的变化看看是不是符合需要。

  • 点击指定控件的某个位置 at 2015年03月25日

    不错,不过想了解一下为何 tap 完需要固定等待 2 秒呢?是因为业务需要?

  • 额,你的 waitAction 等待时间也太长了吧,这个 touch Action 一共花了 10 秒来移动,肯定是龟速啊。
    你改成下面的再试试:

    action.press(200, 250).waitAction(1000).moveTo(10, 250).release().perform();
    
  • 相关源码:
    appium/lib/devices/ios/ios-controller.js

    // we need to change the time (which is now an offset)
    // and the position (which may be an offset)
    var time = 0;
    _.each(touchStateObjects, function (state) {
      if (state.touch[0] === false) {
        // if we have no position (this happens with `wait`) we need the previous one
        state.touch[0] = prevPos;
      } else if (state.touch[0].offset && prevPos) {
        // the current position is an offset
        state.touch[0].x += prevPos.x;
        state.touch[0].y += prevPos.y;
      }
      // prevent wait => press => moveto crash
      if (state.touch[0]) {
        delete state.touch[0].offset;
        prevPos = state.touch[0];
      }
    
    
      var timeOffset = state.timeOffset;
      time += timeOffset;
      state.time = time;
    
      delete state.timeOffset;
    });
    

    相关文档:https://github.com/testerhome/appium/blob/master/docs/cn/writing-running-appium/touch-actions.cn.md

  • 从左边的 log 看,你正在执行的应该是右面第二个 touch 的代码:

    action.press(170, 250).moveTo(150, 250).release().perform();
    

    第一个 log 表明一次性传入了 3 个动作(action)(这里 log 太长了,我就只写前面一小部分):

    --> POST /wd/.....
    

    这个 log 和你的执行代码是一致的,即 appium server 收到的命令是没问题的。
    然后你有疑惑的应该是下一个 log:

    [debug] Pushing command to appium ...
    

    此处的第二个 touch 坐标和你代码不是完全一样。代码是150, 250,而命令则是320, 500。这个应该是做了一个计算:170+150=320, 250+250=500,即moveTo在传坐标时会认为传的是相对于起始元素的偏移量。

    你没有滑动的原因应该是没有加wait方法。你可以尝试在pressmoveTo之间加个wait方法。

  • 能把标题改改,改成类似"xx 错误原因及解决方案"吗?
    看到这标题我还以为是提问帖。。。