How to Test Deep Links on Android (Complete Guide)
Deep links are crucial for a seamless user experience, directing users directly to specific content within your Android application. Ineffective deep linking leads to user frustration, lost conversion
# Practical Guide to Android Deep Link Testing
Deep links are crucial for a seamless user experience, directing users directly to specific content within your Android application. Ineffective deep linking leads to user frustration, lost conversion opportunities, and a damaged brand reputation. Testing these links thoroughly ensures they function as intended across various scenarios.
Why Deep Link Testing Matters
A broken deep link can manifest in several ways, each impacting the user negatively:
- App Not Installed: The user clicks a link expecting to land in the app, but it opens a browser to a "page not found" error or prompts an app store download without context.
- Incorrect Destination: The link lands the user on the app's homepage instead of the intended product page, article, or profile.
- Crashes or ANRs: The app crashes or becomes unresponsive upon opening via a deep link due to unhandled intents or malformed data.
- UI Glitches: The UI elements on the target screen are not displayed correctly or are inaccessible because the app wasn't prepared for the incoming intent data.
- Security Vulnerabilities: Improper handling of deep link parameters can expose sensitive user data or allow unauthorized actions.
What to Test: Comprehensive Deep Link Test Cases
A robust deep link testing strategy involves covering happy paths, error conditions, edge cases, and accessibility.
Happy Path Scenarios
These tests validate the core functionality of your deep links.
- Direct Navigation to Content:
- Test Case: Click a deep link for a specific product (
myapp://products/123). - Expected Result: The app opens directly to the product details screen for item ID
123.
- Navigation with Parameters:
- Test Case: Click a deep link for a search result (
myapp://search?q=android+testing). - Expected Result: The app opens to the search results screen, displaying results for "android testing".
- Deep Link from External App:
- Test Case: Trigger a deep link from an email client, SMS, or another app.
- Expected Result: The correct Android activity launches and displays the targeted content.
- Deep Link to Non-Default Activity:
- Test Case: A link pointing to a specific screen not typically the app's entry point (
myapp://settings/profile). - Expected Result: The app launches and navigates directly to the user profile settings screen.
Error and Edge Case Scenarios
These tests uncover issues when things don't go as planned.
- Invalid or Malformed URL:
- Test Case: Click a deep link with incorrect syntax or missing parameters (
myapp://products/). - Expected Result: The app gracefully handles the error, perhaps showing a toast message or navigating to a general error screen, without crashing.
- Non-existent Content ID:
- Test Case: Click a deep link for a content item that doesn't exist (
myapp://products/99999). - Expected Result: The app displays a "content not found" message or a relevant error state, not a crash.
- Deep Link with Special Characters/Encoding:
- Test Case: Click a link containing spaces or special characters that require encoding (
myapp://search?q=android%20testing%21). - Expected Result: The app correctly decodes and processes the parameters, displaying accurate search results.
- App Not Installed (Revisited):
- Test Case: Attempt to open a deep link when the target app is not installed.
- Expected Result: The system should ideally redirect to the Google Play Store page for the app, or a predefined fallback URL.
- Deep Link to Foregrounded App:
- Test Case: While the app is already running in the foreground, click a deep link.
- Expected Result: The app correctly handles the new intent by navigating to the specified content, rather than creating a new instance or behaving unexpectedly.
- Deep Link to Backgrounded App:
- Test Case: While the app is running in the background, click a deep link.
- Expected Result: The app resumes from the background, launches the correct activity, and displays the targeted content.
Accessibility Considerations
Deep links must be accessible to all users.
- Descriptive Link Text:
- Test Case: Review the text used for deep links in emails, SMS, or web pages.
- Expected Result: Link text should clearly indicate the destination (e.g., "View Product: Awesome Widget" instead of "Click Here"). This is more of a content review, but directly impacts deep link usability.
- Content Accessibility Post-Navigation:
- Test Case: After navigating via a deep link, ensure all content on the target screen is accessible via screen readers and offers sufficient touch target sizes.
- Expected Result: Screen readers announce content correctly, and interactive elements meet WCAG 2.1 AA touch target requirements.
Manual Deep Link Testing Approach
Manually testing deep links requires careful execution of predefined steps.
- Prerequisites: Ensure the target Android app is installed on a test device or emulator.
- Generate Test Links: Create a list of deep links covering the scenarios outlined above.
- Trigger Links: Use various methods to trigger these links:
- ADB (Android Debug Bridge): This is the most reliable method for precise testing.
adb shell am start -W -a android.intent.action.VIEW -d "myapp://products/123" com.your.package.name
Replace "myapp://products/123" with your deep link URI and com.your.package.name with your app's package name. The -W flag waits for the activity to finish, which is useful for debugging.
- QR Codes: Generate QR codes for your deep links and scan them using a QR code reader app on the device.
- Web Browser: If your app is configured for web-based deep linking (Universal Links/App Links), navigate to the associated URL in the device's browser.
- Email/Messaging Apps: Send yourself emails or messages containing the deep links and tap them from within those apps.
- Observe and Verify:
- App Launch: Does the app launch?
- Correct Screen: Does it land on the intended screen?
- Content Display: Is the content (product details, search results, etc.) displayed correctly?
- Error Handling: If an error scenario is tested, is the error handled gracefully without crashes?
- Performance: Is there any noticeable lag or ANR?
- Accessibility Check: Use TalkBack to navigate the content on the target screen. Verify element announcements and focus management.
Automated Deep Link Testing
Automating deep link tests significantly improves efficiency and repeatability.
- Appium (for Android): While Appium primarily automates UI interactions *within* an app, you can use it in conjunction with ADB commands to launch deep links.
- Execute an ADB command to open the deep link.
- Wait for the app to launch and the target activity to become visible.
- Use Appium to interact with elements on the target screen to verify content and functionality.
from appium import webdriver
import subprocess
desired_caps = {
"platformName": "Android",
"deviceName": "emulator-5554", # Or your device UDID
"appPackage": "com.your.package.name",
"appActivity": "com.your.package.name.MainActivity", # Your app's main activity
"automationName": "UiAutomator2"
}
# Launch deep link using ADB
deep_link_uri = "myapp://products/123"
package_name = desired_caps["appPackage"]
subprocess.run(f"adb shell am start -W -a android.intent.action.VIEW -d \"{deep_link_uri}\" {package_name}", shell=True)
# Initialize Appium driver (wait for app to launch)
driver = webdriver.Remote("http://localhost:4723/wd/hub", desired_caps)
# Now use driver to assert content on the target screen
# For example:
# product_title_element = driver.find_element_by_id("product_title")
# assert "Awesome Widget" in product_title_element.text
driver.quit()
- Espresso (Android Native): For more integrated testing, Espresso can launch activities directly with intents.
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.intent.Intents
import androidx.test.espresso.intent.Intents.intended
import androidx.test.espresso.intent.matcher.IntentMatchers.hasAction
import androidx.test.espresso.intent.matcher.IntentMatchers.hasData
import androidx.test.ext.junit.rules.ActivityScenarioRule
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.hamcrest.CoreMatchers.allOf
import org.junit.After
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
@RunWith(AndroidJUnit4::class)
class DeepLinkTest {
@get:Rule
var activityRule: ActivityScenarioRule<MainActivity> = ActivityScenarioRule(MainActivity::class.java)
@Before
fun setup() {
Intents.init() // Initialize Intents recording
}
@After
fun tearDown() {
Intents.release() // Release Intents
}
@Test
fun testProductDeepLink() {
// Launch the app and then trigger the deep link intent
// This requires careful setup to ensure the intent is captured correctly.
// A common approach is to launch an activity that handles the intent.
// For direct testing of an incoming intent, you might need to craft a test rule.
// Example of asserting an intent was sent (if your app broadcasts it)
// For testing actual deep link handling, you'd typically launch an activity that
// *processes* the deep link, then verify its UI state.
// A more direct way to test deep link handling within Espresso:
// Launch an activity that processes a
Test Your App Autonomously
Upload your APK or URL. SUSA explores like 10 real users — finds bugs, accessibility violations, and security issues. No scripts.
Try SUSA Free