Appium has the ability to start Android emulators and iOS simulators in a "headless" mode. This means that the devices won't have any graphical user interface; you won't see them on your desktop, but they will still be running silently, testing your app.
Actually, the devices won't run silently. They will still emit sounds through your speakers, access the microphone, or anything else they usually do, you just won't have a window on your screen which shows what they're doing, and you won't get those interactive buttons.
Most surprisingly, the emulators and simulators still render the app UI, they just don't display it. This means that the video recording and screenshot commands still work as usual. The only thing we lose when running in headless mode is the ability for a user to manually intervene and manipulate a device during a test session.
This style of headless virtual device is a little different from headless browsers, which do not render the UI and therefore enable decreased test times because the costly process of deciding how to lay everything out on the screen is skipped. Sadly, running headless emulators and simulators will save a little bit of system resources by not running the actual windowed application, but compared to the CPU and memory required to run the device, this is minimal.
Headless simulators and emulators should run exactly the same as their graphical counterparts, but I encountered an issue running our usual example app in a headless Android emulator! The issue seems to have something to do with ReactNativeNavigation, but this shows that something is different about Android emulators in headless mode.
Headless emulators and simulators are most useful for device farms which run devices on servers which have no graphical window manager in the first place. Though rare, running OSX fully headless is possible, in which case it is convenient that simulators can still be run.
Desktop tools can also take advantage of this features. Imagine a tool like Appium Desktop which starts its own emulators and simulators but doesn't want to confuse the user by popping up extra windows. The tool could use the headless feature to hide these windows from the user.
(In terms of using headless devices on my personal computer, the best use case I discovered is to stop the iOS simulator from stealing my window focus and popping up over whatever I'm doing whenever a test starts up.)
How to Run Headless Emulators and Simulators
It's simple! Just set the following desired capability to true:
If you're testing on android, you will have to provide the avd desired capability so that Appium starts the emulator with the necessary arguments. Not specifying the avd results in Appium using the current emulator already running, and of course if it's already running with a UI, the UI will stay visible.
iOS has no such issue; if you set isHeadless to true, then Appium will shut down any currently running simulators and restart them in headless mode.
Unless you instructed Appium to shut down the device afterwards, the headless emulators and simulators will still be running after your session, but you won't see them unless you check via the simctl utility or adb.
How Does it Work?
For iOS simulators, the actual simulator is a separate process from the Simulator.app app. When Appium starts an iOS simulator normally, it has to start the simulator using the simctl utility, and then it launches Simulator.app. When running in headless mode, Appium just skips the second step. If you want to start playing with a simulator which is running in headless mode, launch Simulator.app and a window will be displayed for all currently running simulators. Warning: quiting Simulator.app shuts down all simulators!
For headless Android emulators, Appium starts the emulator via ADB as usual, and adds the -no-window flag. Documentation can be found here.