• @Lihuazhang rn 手工测试的覆盖率也能收集到咯。

  • 这应该是社区第一篇写 AS 插件开发和发布的文章,开眼界了。

    话说,火线现在有在计划做阈值校验功能吗?类似于设定 xx 级别的问题数量大于 xx 后,扫描命令 exit code 不为 0 。这样会更方便把火线接入持续集成或者 git commit hook ,更好地止住静态扫描发现的问题数量。

  • 这块我后面写个帖子吧。流程本身其实比较简单。

  • 确定贴全了吗?应该至少有 http method 之类的信息吧。

  • 请使用 markdown 排版。。。

  • 视野决定广度,广度决定深度。总是想用到在学,结果会发现你永远不会用到,因为你根本想不到。

  • 看了下 CMap 的实现,我的理解是针对 TextField,Button,Checkbox 三种常用控件的常用操作都封装成 get 和 set 方法,简化掉不同控件的各种不同的调用(如 TestField 的 send_keys,Button 的 click,CheckBox 的 click ,所以用例里面只需要对控件对象进行 set 和 get 就好了。

    例如 TesterHome 例子里的就是遍历这个字典,分别对 User,Pwd 和 Remember 三个控件进行:

    User set 为 123(send_keys)
    校验 User 当前的值是否为 123
    Pwd set 为 456(send_keys)
    校验 Pwd 当前的值是否为 456
    Remember set 为 TRUE(click)
    校验 Remember 当前的值是否为 TRUE(is_selected)

    这种方式确实减少了一些学习成本,而且个人觉得大部分控件应该都能用 set 和 get 进行简化的。

    至于自动回归和地图化,很感兴趣,但信息有点少,表示没看懂。希望楼主可以补充一些例子说明下~

  • python HTMLTestRunner 中文乱码 at 2017年05月21日

    个人觉得这个不是乱码,而是你的文字是以 unicode 编码值的形式显示出来了。乱码一般是说用了错误的解码器解码,例如用 gbk 解码 utf-8 ,一般特征是长得像火星文,各种未见过的生僻字。你可以在 http://tool.chinaz.com/tools/unicode.aspx 做一下转换,就会发现实际上显示的就是你想用的中文,只是显示形式不对。

    我目前了解的会出现这种情况的场景,是用了 repr 方法解析 unicode 字符串:

    unicode_str = u'中文'
    
    # 这样就会显示 u'\u4e2d\u6587'
    print repr(unicode_str)
    

    建议可以在 if isinstance(e,str):if isinstance(o,str): 加个断点,看下此时中文是否已经变成了 unicode 编码值?

  • 金枪鱼三明治 at 2017年05月21日

    除了技术,我们也要有诗和远方嘛~

  • 时间过得好快,支持~

  • 哈哈,能解决你们的问题就好。我们当初也在这个问题上卡了 2-3 天,尝试了很多办法才解决的。

  • 之前也踩了这个坑,原因是我们源码打包是在 mac 上做的,但生成覆盖率报告改成了 windows ,默认编码不一样。

    修改方案:在 gradlew jacocoTestReport 命令直接添加指定编码的参数,即改为 gradlew -Dfile.encoding=UTF-8 jacocoTestReport

  • openstf 模块解读--websocket at 2017年05月15日

    没事,这个问题我发公众号检查的时候也没发现。后面我们都留意好这些细节吧。

  • 特意去看了下 stf 的源码,终于大致了解了应用场景:

    function install() {
          log.info('Checking whether we need to install STFService')
          return getPath()
            .then(function(installedPath) {
              log.info('Running version check')
              // 此处通过 adb 的 exec app_process 命令获取到 STFService 的 version 值,进而判断是否需要继续安装 STFService 
              return adb.shell(options.serial, util.format(
                "export CLASSPATH='%s';" +
                " exec app_process /system/bin '%s' --version 2>/dev/null"
              , installedPath
              , resource.main
              ))
              .timeout(10000)
              .then(function(out) {
                return streamutil.readAll(out)
                  .timeout(10000)
                  .then(function(buffer) {
                    var version = buffer.toString()
                    if (semver.satisfies(version, resource.requiredVersion)) {
                      return installedPath
                    }
                    else {
                      throw new Error(util.format(
                        'Incompatible version %s'
                      , version
                      ))
                    }
                  })
              })
            })
            .catch(function() {
              log.info('Installing STFService')
              // Uninstall first to make sure we don't have any certificate
              // issues.
              return adb.uninstall(options.serial, resource.pkg)
                .timeout(15000)
                .then(function() {
                  return promiseutil.periodicNotify(
                      adb.install(options.serial, resource.apk)
                    , 20000
                    )
                    .timeout(65000)
                })
                .progressed(function() {
                  log.warn(
                    'STFService installation is taking a long time; ' +
                    'perhaps you have to accept 3rd party app installation ' +
                    'on the device?'
                  )
                })
                .then(function() {
                  return getPath()
                })
            })
    

    我理解这种方式最大的用处,是给一个相比 intent 更为隐秘的入口 (intent 毕竟比较公开) 。目前想到的应用场景,和 @heyniu 想的差不多,通过命令行设定一些内部参数,比如后端服务的 ip 地址(我们有多个环境),然后再启动 apk 。

    有一些 android 系统为 app 提供了的接口 adb shell 没有现成命令使用,也可以这么用,例如 appium 里面经典的获取当前网络状态(这个系统接口貌似只有 app 才能调用,adb shell 调用不了)。

  • 缺少接口协议文档,正确请求的抓包记录,社区的同学也帮不了你呀。。。

    PS:500 错误是服务端错误,建议先找开发同学了解下到底是什么原因,不一定是你的请求有问题。

  • 小米这个 usb 安装的开关应该是他们自己加的,确实比较隐蔽。。。不过这个开关不开,adb install 的程序应该都装不上吧,还是比较容易发现的。

  • openstf 模块解读--websocket at 2017年05月12日

    发了微信公众号后,有同学反馈原文第二章有些地方 websocket 错写成了 webdocket 。我现在更正过来了,如果其它地方也有发过这个文章,也一并更正吧。

  • loadrunner 和 jmeter 大 PK at 2017年05月11日

    这个 pk 不够大呀。。。

  • 我们目前采用加入源码的方式,但前期由于我们自己的覆盖率收集也不大完善,所以通过把添加的代码做成 git patch ,然后每次打包通过 git apply patch 的形式把为了覆盖率添加的配置项及代码加上,再打出带有覆盖率收集的包(在 BaseActivity 中的 onStop 加了自动生成和上传覆盖率的功能)。测试团队在测试环境统一使用带有覆盖率收集的包进行测试,这样收集到的覆盖率信息相对比较齐全,分析价值比较大。

    也和开发团队沟通过,他们的诉求是只要能确保对外发布的 release 的包不带有覆盖率相关信息(即采用 release 方式打包时,覆盖率的相关代码全部不生效或不会包含在编译后的包中),开发是可以接受把覆盖率收集加入到他们的代码仓库中的。

  • 框架不是我写的,建议直接看源码学习吧。目前根据我的了解,用的应该是 testNG 本身提供的并行执行机制。

  • 不用急,你已经知道好代码长什么样了,下一步就是怎么逐步优化,写出好代码了。

  • 把 config.log 贴上来给大家看看?

  • 好久没搞这个了,不大清楚。

  • UIAutomation 已经被淘汰了吧,XCode 8 开始就不支持了。现在应该用 UI Testing Bundle 了。

    至于 UIAutomation 的多模拟器并行,以前在 GTAC 的视频看到过 Uber 有类似的演示,有没有说具体技术细节不是很记得。要做到模拟器同时多开,需要用到一个很重要的工具:FBSimulatorControl

  • 学习下怎么用 markdown 语法把,骚年。。。现在的排版代码块部分太乱了,所有缩进都没有了。