Android deep links enter an app through the same intent resolver path that a browser, notification, or campaign URL uses. Testing that path with Espresso catches broken route patterns before a link opens the wrong screen or falls back to a browser.

An instrumented test can build the ACTION_VIEW intent, scope it to the app under test, launch it with ActivityScenario, and let Espresso assert the visible destination state. Scoping the intent with the package name keeps the launch focused on the app route instead of the device resolver.

A product-detail link keeps the assertion concrete because the launched URL must show the product title for the linked item. Replace the host, path, Activity, and view IDs with values from the app, and keep one assertion tied to the destination that proves the deep link loaded the intended content.

  1. Add or confirm the AndroidX Test dependencies in the app module.

    Use espresso-core 3.7.0 with androidx.test:core 1.7.0, runner 1.7.0, and ext:junit 1.3.0, or keep the same release train already used by the project.
    Related: How to configure an Android project for Espresso

  2. Confirm that the Activity or Navigation route accepts the link shape that will be launched.

    The route should accept ACTION_VIEW with DEFAULT, BROWSABLE, the https scheme, the expected host, and the product path prefix. android:exported=“true” is required for activities with intent filters on recent Android versions.

  3. Create the deep-link instrumented test under the app's src/androidTest tree.
    package com.example.app
     
    @RunWith(AndroidJUnit4::class)
    class DeepLinkTest {
      @Test
      fun opensProductDeepLink() {
        val context: Context =
          ApplicationProvider
            .getApplicationContext()
     
        val intent =
          Intent(
            Intent.ACTION_VIEW,
            Uri.parse(
              "https://example.com/p/42"
            )
          )
            .addCategory(
              Intent.CATEGORY_BROWSABLE
            )
            .setPackage(
              context.packageName
            )
     
        ActivityScenario
          .launch<MainActivity>(
            intent
          )
          .use {
            onView(withId(R.id.title))
              .check(
                matches(
                  withText("Espresso")
                )
              )
          }
        }
    }

    Let Android Studio add the AndroidX Test, Espresso, JUnit, Intent, Uri, and Context imports. The package scope avoids external browsers and chooser UI; remove it only when the goal is to test Android's system resolver or verified App Links handoff outside the app package.

  4. Run the instrumented tests on an emulator or connected device.
    $ ./gradlew \
    connectedDebugAndroidTest
    Task connectedDebugAndroidTest
    Started 1 test on emulator
    Finished 1 test on emulator
    
    BUILD SUCCESSFUL in 38s

    If Gradle reports that no devices are connected, start an emulator or attach a device before rerunning the task. Use an instrumentation runner class argument when the project has many instrumented tests and only DeepLinkTest should run.

  5. Open Gradle's connected Android test report and confirm DeepLinkTest marks opensProductDeepLink as passed.