Setting Up App State for Efficient Functional Testing with Appium
Functional testing is crucial for ensuring the quality of mobile applications, but it comes with a ๐ฌ๐ฉ๐๐๐ ๐ฅ๐ข๐ฆ๐ข๐ญ due to the time required for taps, keystrokes, loading data from the network, and animations. While these delays ensure high-fidelity testing, simulating real-life scenarios as closely as possible, they can become a bottleneck when multiple tests require the same initial setup, such as logging in.


The Problem: Redundant App State Setup
High-fidelity testing becomes inefficient when many tests rely on the same starting point. For instance, logging into an app might involve filling out several text boxes, tapping buttons, and waiting for network verification. This process can take 20 to 25 seconds. For a suite of 50 tests, each requiring a login, this adds up to approximately 20 minutes of wasted time. Moreover, repeating this setup increases the risk of flaky tests.

The main objective of testing is to make assertions about app behavior. To do this, we need to interact with the app via the UI, such as filling in a text field and tapping a button. However, these interactions often require a proper setup of the application state. For instance, if weโre testing an e-commerce app, our assertion might involve the quantity of items in the shopping cart. To make this assertion, we need to add an item to the cart, which is an essential part of the test.

However, setting up the state often involves preliminary steps unrelated to the core functionality being tested, like creating a user account and logging in. This requirement introduces two main issues:
1. ๐๐ฏ๐ด๐ถ๐ณ๐ช๐ฏ๐จ ๐ต๐ฉ๐ฆ ๐๐ต๐ข๐ต๐ฆ ๐๐ด ๐๐ฆ๐ข๐ฅ๐บ: We must ensure no interactions occur before the state is fully set up, or our assertions will likely fail. This involves using explicit waits to ensure the app is ready for interaction.

2. ๐๐ช๐ฎ๐ฆ-๐๐ฐ๐ฏ๐ด๐ถ๐ฎ๐ช๐ฏ๐จ ๐๐ฆ๐ต๐ถ๐ฑ: Setting up application state through the UI can be slow. While the actual test steps might take seconds, preparing the app state can take minutes, wasting time and increasing unreliability. This issue compounds when multiple tests require the same setup, leading to significant inefficiency.

While it might not be possible to speed up the login steps using Appium directly, there are strategies to bypass these repetitive setups and start tests in the desired state. To address these challenges, we need strategies to quickly and reliably set up the app state, ensuring efficient and effective testing.
Five Strategies to Set Up App State Instantly
Here are five techniques to help you set up your app state efficiently, minimizing repetitive tasks and enhancing test reliability.
1. Custom Android Activities (Android)
Android apps can use Activities to represent different parts of the application. You can design an Activity to set up the desired state.

Using Appiumโs native mobile startActivity
command, we can launch an Activity directly:
driver.execute_script("mobile: startActivity",
{"component": f"{package_id}/{activity_name}"})
We can also use the appPackage
and appActivity
capabilities to start the session in the specified Activity. Remember to remove any test-specific activities from the production build.

2. Custom Launch Arguments (iOS)
For iOS apps, which lack Activities, you can use launch arguments โ command-line flags read by the running application. These flags can include data like usernames and passwords for an initial UI-less login, accessed via the processArguments
capability in Appium:
{
"processArguments": "-view login -viewparams 'your_username,your_password'"
}

The app developer must configure the app to recognize and handle these flags and ensure the production build ignores them.
3. Test Nexus
The Test Nexus, a.k.a. Kitchen Sink, technique involves creating a special view in your app, available only in the test build, with links to various states. For example, links like Logged-in Home or Cart With 1 Item can take the app to the respective state. This approach is cross-platform and straightforward, saving time by bypassing repetitive setup steps.

4. Deep Links
Deep Links are commonly used in marketing campaigns to direct users to specific pages within an app, provided the app is already installed on their device. In test automation, we can leverage this technique to save significant time on setup steps by directly navigating to the desired page.
Deep linking uses OS-level features where custom scheme URLs direct the app to a specific state. For example:
your_app://test/login/:username/:password
Clicking this URL or using Appiumโs driver.get()
command can launch the app in the desired state:
driver.get("your_app://test/login/your_username/your_password");
This method requires the app to have a custom scheme registered and a URL controller to parse and navigate accordingly.
5. Application Backdoors
This technique involves exposing internal methods of the application for testing purposes. These methods, accessible via a custom RPC channel, can set up the necessary state. With Appiumโs Espresso Driver, we can interact with appโs internal methods from within the automation context.

Conclusion
Implementing these techniques can significantly reduce the time and potential flakiness of your tests by eliminating redundant state setups. Collaboration with your development team to create these mechanisms will yield quicker and more reliable builds. Despite the initial effort, the long-term benefits for testing efficiency and application stability are substantial.
By optimizing the state setup process, you ensure that your functional tests are both high-fidelity and time-efficient, ultimately contributing to a smoother and more reliable testing workflow.