How to Test Deep Links in Android: Three Different Options
Testing deep links in Android takes some effort, but you have all of the tools you need with ADB and Espresso. Here's how to get started.
Deep links are an important feature in mobile applications. By taking users directly to specific sections or pieces of content, they increase engagement. But, they're not easy to implement and require careful testing. If you don't make verifying deep links a part of your testing process, you risk leaving users disappointed and angry instead of engaged.
Let's look at three different options for testing deep links.
Testing Deep Links on Android
To follow this tutorial, you'll need to install Android Studio. This tutorial works with Kotlin version 1.15.x or newer and Android SDK version 29 or newer.
We'll use a simple Kotlin Android application with two types of deep links; application links and web links. We'll very briefly look at how to implement a set of deep links and then dive right into how to test them. To focus on testing techniques, both the overall application and the links themselves are very simple. The application is based on the "Basic Activity" sample application in Android Studio.
Android applications define their links in AndroidManifest.xml. Let's start with an overview of the two types of links and how to define them in the application manifest.
Application links use a proprietary scheme instead of the standard HTTP or HTTPS. You'll encounter them most often encountered on the device since we use them to move users between apps or application sections.
Here's a definition of an application link that uses dleg for the scheme.
So, Android will route links targeted to dleg://www.example.com to this application.
Web links use http and https.
This definition looks largely the same as the previous one, except it has two scheme entries and the autoVerify="true" parameters.
If you want Android to automatically route links for your domain to your application instead of the website, you need to verify the links using one of the methods spelled out in the documentation. If you don't, Android will prompt users with an option to open the links in your app or in a web browser. Take care of this in advance, or automated tests will fail when the operating system tries to prompt a use that isn't there.
The application handles deep links in MainActivity's onCreate method. This method passes the Intent to handleIntent, which verifies that it isn't carrying the default MAIN action. If it doesn't, the method passes the intent to ProcessDeepLinkIntent.
This method checks to see if the op parameter is present. If it's present, it starts a new activity. If not, it checks for the text parameter and displays its value in the main view.
So, we have a simple application that extracts and uses values from a deep link. A more sophisticated app might use the values of the op parameter to perform more than one action. Or, it might use a parameter to display an item for sale or send a user to a specific screen to read a message.
Let's look a how we can test these links.
Testing Deep Links With ADB
The syntax for sending an intent requires eight arguments:
- -s <device id> to select the correct device
- shell - to send a shell command
- am - to call the activity manager in the shell
- start to start an activity
- -W to wait for the activity to finish before returning
- -a android.intent.action.VIEW to indicate a link
- -d <link text>
- <application package>
Here's a shell listing the available devices and then sending an application deep link to the connected emulator. Note that the URI escapes the spaces with a \ to avoid the shell trying to interpolate them as individual arguments.
Here's the result in the emulator:
The application received the deep link and displayed the text for us!
Now, let's try a web link.
The emulator displays the link text.
ADB and the activity manager don't differentiate between application and web links, so we only need to change the link we send with the intent.
They're handy tools for verifying deep links as you're coding since you can use the shell to send links with varying parameters and make sure your code works as expected. They're also the only test tool we'll cover here that verifies the contents of your manifest file since they test your entire application instead of individual units.
But they're not well suited for automated tests since you still need to look at the emulator to check your results.
Testing Deep Links With Espresso Intents
Espresso is Google's toolkit for testing Android UIs, and Espresso-Intents is an extension for verifying and stubbing Android intents. We can use this extension to ensure that our application executes the intents we expect when we send it a link.
Espresso-intents make these checks easy with the intended() method, which verifies that it saw an Intent that matches the given criteria during the test. With some simple setup, we can use it to check that the application sees the links we pass in.
When the application is sent a link with the op parameter, it initiates a new activity by creating another Intent. Here is a test of that Android application deep link:
First, we need an ActivityTestRule to run the activity, so we create it on line #6.
Then, in the test method, we initialize Espression-Intents with Intents.init() on line #11, so it will capture the intent. Next, we create the intent on line #13 and pass it to ActivityTestRule.launchActivity(). This executes the test.
Finally, we use intended() on line #15 with a matcher to verify that an Intent with a NewActivity component was seen during the test.
Run this test in Android Studio:
It's all green!
Testing Deep Links With ActivityScenarioRule
We still need an automated test verifying that deep links result in the UI changes we expect. For this, we can use ActivityScenarioRule and Kotlin's ability to easily access views inside a unit test.
We used ActivityTestRule in the previous test because it plays nicely with Espresso-Intents, but Google deprecated this class in an earlier version of Espresso. We're better off using ActivityScenarioRule when we can. It has a more concise syntax and, as you'll see, makes tests easy to read and write.
Here's a test for the Android application deep link:
On line #4, we create an Intent with the link and action required for the test.
On line #7, we create the ActivityScenarioRule and initialize it with the Intent.
Lines #11 and #12 get the ActivityScenario from the rule and execute it inside a closure. Inside the closure, we use the activity to find the TextView that should contain the text supplied by the deep link. So, we can verify that the link worked with an assertion.
Run this test in Android Studio and check the result:
Like with the ADB tests, the only difference for the web links is the contents of the Intent.
If you've taken care of the link verification, your tests will pass for web links, too.
Verify Your Android Deep Links
This tutorial looked at three ways to test deep links in Android. ADB makes it easy for developers to verify links as they code. Espresso has tools for ensuring the Android UI responds correctly when it's sent a link, and Espresso-Intents is useful for stubbing and verifying intents inside tests.
Android has a robust development ecosystem, with a cross-platform IDE in Android Studio and a versatile testing library in Espresso.
Challenges with Testing Deep Links
One of the primary challenges with writing durable automated tests for deep linking is the integration of third party apps. Deep links are crucial to drive user acquisition, engagement, adoption, and referral loops, but they don't come from within your app. You'll need to test across email, SMS, QR codes, social platforms, push notifications from the lock screen, and many more scenarios. Writing durable tests for these scenarios is quite challenging, as it requires you to leave the app context.
This is where Mobot can help. Using real, mechanical robots testing on physical devices, Mobot can efficiently automate the testing of deep linking in every scenario needed. Want to see it in action? Click here to view Mobot testing deep linking using real robots.
This post was written by Eric Goebelbecker. Eric has worked in the financial markets in New York City for 25 years, developing infrastructure for market data and financial information exchange (FIX) protocol networks. He loves to talk about what makes teams effective (or not so effective!).