I have calabash-android set up working perfectly with a default scenario (using cucumber
to run tests or calabash-android console
to enter REPL mode).
However, under some scenarios, it turns out to be pretty useful to be able to attach to an app that's already running. For instance, I would start an app in debug mode and start the tests to be able to set breakpoints and check why certain features don't work as expected in my scenarios.
When it comes to Calabash on iOS, this task is really straightforward: no additional preparation needed as the app starts with a test server bundled in and I can attach calabash to it at any time. However, Calabash Android seems to be force-quitting the app every time I try to start calabash having the app running.
Is there any way around it?
EDIT Looks like the below answers didn't help much, but I still hope someone (calabash devs, where are you?) will stumble upon this one day. I have spent some time discovering the issue myself, and that's what the specific issue is:
- Start the app in Debug mode (using Xamarin, for instance)
- Start
calabash-android console PATH_TO_APK
- Try issuing any commands (e.g.
query("*")
) – it fails with a message KeepAliveDisconnected - Try running start_test_server_in_background – the app is killed and debug session is terminated
Digging deeper into details, I found out that start_test_server_in_background in fact runs shell am instrument
with sh.calaba.instrumentationbackend.CalabashInstrumentationTestRunner
being instrumentation backend and a bunch of other flags describing which app to instrument, what port to use etc.
Thus being said, the following would help a lot: is it possible for shell am instrument to attach to a running app?
Great question, and the simple answer is:
At least not on Android (I cannot attest to iOS). Why? Calabash has to establish hooks on the app you want to run on before you can run any tests on the app. This is due to a mixture of reasons regarding the Android stack.
The first reason is security. Android locks down apps in the installation phase based on the permissions set for it. Because of this design, Calabash (or any other app-process-interfering script) will not be able to execute in the middle of an app process. As you have found out, you can still run Calabash tests together with the start of the app as Android will validate Calabash for this purpose.
The second reason is architecture. Android is designed as layers of processes and views. What you are trying to do will probably interfere with more than one process on a variety of levels.
The best you can do is start Calabash for an App without reinstalling it, but that is the most Android will allow you to do.
Finally, I apologize if this answer does not delve into the very technical details, these were the answers given to me during a particular Hackathon as I struggled with a similar issue.