【问题标题】:Calabash-android: attach to running appCalabash-android:附加到正在运行的应用程序
【发布时间】:2015-08-04 16:44:58
【问题描述】:

我已将 calabash-android 设置为在默认场景下完美运行(使用 cucumber 运行测试或使用 calabash-android console 进入 REPL 模式)。

但是,在某些情况下,能够附加到已经运行的应用程序是非常有用的。例如,我会在调试模式下启动一个应用程序并启动测试,以便能够设置断点并检查为什么某些功能在我的场景中不能按预期工作。

对于 iOS 上的 Calabash,这项任务非常简单:不需要额外的准备工作,因为应用程序从捆绑的测试服务器开始,我可以随时将 calabash 附加到它。但是,每次我尝试启动使应用程序运行的葫芦时,Calabash Android 似乎都会强制退出该应用程序。

有什么办法吗?

编辑 看起来下面的答案并没有太大帮助,但我仍然希望有人(葫芦开发者,你在哪里?)有一天会偶然发现这一点。我花了一些时间自己发现了这个问题,这就是具体问题所在:

  1. 在调试模式下启动应用程序(例如使用 Xamarin)
  2. 开始calabash-android console PATH_TO_APK
  3. 尝试发出任何命令(例如 query("*")) - 失败并显示一条消息 KeepAliveDisconnected
  4. 尝试运行 start_test_server_in_background - 应用程序被终止并且调试会话被终止

深入研究细节,我发现 start_test_server_in_background 实际上运行 shell am instrumentsh.calaba.instrumentationbackend.CalabashInstrumentationTestRunner 是检测后端,还有一堆其他标志描述要检测的应用程序、要使用的端口等。

因此,以下内容将有很大帮助:shell am instrument 是否可以附加到正在运行的应用程序

【问题讨论】:

  • Calabash 必须通过检测命令启动应用程序,以使其服务器以允许其查询和控制应用程序的权限运行。 stackoverflow.com/questions/10942049/… 建议您可以将 -e 'debug true' 添加到 Calabash 的检测命令中,然后使用“附加到正在运行的进程”按钮(在 Android Studio 中调试图标的一侧)确保您的应用程序清单设置为可调试。

标签: android cucumber calabash calabash-android android-instrumentation


【解决方案1】:

我刚刚成功地做到了。没什么大不了的——我只是在失败点暂停了 Calabash 测试,使用了一个暂停 Ruby 的“After”钩子(实际上,它使用 IRB,但这是偶然的):

After do |scenario|
  if scenario.failed? && scenario.source_tag_names.include?('@wip') && PLATFORM == ANDROID
    require 'irb'
    require 'irb/completion'
    ARGV.clear
    IRB.start
  end
end

然后启动Android Studio,单击工具栏中正常调试图标右侧的“将调试器附加到Android进程”按钮,单击“无法连接到adb”弹出窗口告诉它尝试再次(没有自己杀死/重新启动 adb),单击它提供给我的进程,然后......它连接愉快。我成功设置断点并命中,前后在控制台中执行了query("*")。

我不必更改 Calabash 仪器命令来添加 -e 'debug true' 或其他任何内容。

唯一的问题是当我关闭它时,Android Studio 取出了 adb 服务器,但我认为这是一个已知的错误^H^H^H功能。

也许如果您创建一个“And Cucumber 等待按键”步骤来等待您敲击主机的键盘,这样您就可以将 Android Studio 附加到手机的进程并在恢复之前设置断点。显然——断点会打乱脚本中的任何时间。

【讨论】:

    【解决方案2】:

    很好的问题,简单的答案是:

    没有

    至少不是在 Android 上(我无法证明 iOS)。为什么? Calabash 必须在要运行的应用程序上建立挂钩,然后才能在应用程序上运行任何测试。这是由于有关 Android 堆栈的多种原因造成的。

    第一个原因是安全性。 Android 根据为其设置的权限在安装阶段锁定应用程序。由于这种设计,Calabash(或任何其他干扰应用程序进程的脚本)将无法在应用程序进程的中间执行。正如您所发现的,您仍然可以在启动应用程序的同时运行 Calabash 测试,因为 Android 将为此目的验证 Calabash。

    第二个原因是建筑。 Android 被设计为进程和视图层。您正在尝试做的事情可能会在多个层面上干扰多个进程。

    您可以做的最好的事情是在不重新安装应用程序的情况下启动 Calabash,但这是 Android 允许您做的最多的事情。

    最后,如果这个答案没有深入研究非常技术性的细节,我深表歉意,这些是我在特定的 Hackathon 中遇到类似问题时给我的答案。

    【讨论】:

    • 听起来很合理,但是单元测试的调试如何工作呢?事实上,他们使用与 Calabash 相同的仪器运行程序,但我们绝对可以在应用程序通过单元测试时对其进行调试。有什么想法吗?
    【解决方案3】:

    当您在同一端口上启动新服务器时,Calabash-Android 会停止任何测试服务器和被测应用。

    如果您希望将控制台附加到正在运行的测试中,只需打开控制台 (bundle exec calabash console ..) 并发出手势和查询,而无需使用 start_test_server_in_background 启动应用程序。一种常见的模式是使用 gem pry,使用方法 binding.pry 来暂停测试并启动控制台。

    请注意,当黄瓜场景失败或结束时,生成的 Calabash-Android 黄瓜骨架将自动运行shutdown_test_server。您可以删除该调用并附加一个控制台。

    【讨论】:

    • 正如我所提到的,它在 iOS 上很好,但在 Android 上它似乎不起作用 - 请注意我想附加到一个已经运行的应用程序,因为我想调试应用程序,而不是测试。并且由于该应用程序已被其他人启动,因此不会启动 TestInstrumentation,因此控制台无法连接到该应用程序。
    • 好吧,正如@bernlim 所说,Calabash-Android 目前不支持附加到尚未由 Calabash 框架启动的应用程序。用例是什么,您要解决什么问题?
    • 其实很简单:我想调试测试。比如说,我注意到一个场景失败,我想在应用程序运行时调试它——这似乎可以节省时间,因为某些场景可能非常复杂并且涉及在服务器上预先配置的种子数据,这意味着复制手动问题有点痛苦
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多