Skip to content
Tolinku
Tolinku
Sign In Start Free
Deep Linking · · 5 min read

Best Deep Link Testing Tools and How to Use Them

By Tolinku Staff
|
Tolinku industry trends dashboard screenshot for deep linking blog posts

Deep links fail silently. When a Universal Link does not open the app, the user just sees a web page. No error message, no crash log, no alert. You only find out when someone reports it, or when your analytics show a 40% fallback rate. Testing catches these issues before users encounter them.

This guide covers tools and techniques for testing deep links. For debugging specific issues, see debugging deep links: a step-by-step guide. For implementation, see how to implement deep links from scratch.

Verification File Validators

Apple App Site Association Validator

Apple provides a validator for AASA files:

App Search API Validation Tool

Enter your domain and the tool checks:

  • AASA file is accessible at /.well-known/apple-app-site-association
  • Returns HTTP 200 (not a redirect)
  • Valid JSON format
  • Correct content-type: application/json header
  • applinks section exists with valid app IDs

You can also check manually:

# Fetch and validate AASA
curl -s https://yourdomain.com/.well-known/apple-app-site-association | python3 -m json.tool

# Check headers
curl -sI https://yourdomain.com/.well-known/apple-app-site-association
# Must return: content-type: application/json (NOT text/html or text/plain)
# Must return: HTTP 200 (NOT 301/302 redirect)

Google provides a validator for assetlinks.json:

Statement List Generator and Tester

Enter your domain and Android package name. The tool verifies:

  • assetlinks.json is accessible at /.well-known/assetlinks.json
  • File contains a valid statement linking the domain to the app
  • Package name matches
  • SHA-256 certificate fingerprint matches
# Manual check
curl -s https://yourdomain.com/.well-known/assetlinks.json | python3 -m json.tool

# Verify specific link
curl -s "https://digitalassetlinks.googleapis.com/v1/statements:list?source.web.site=https://yourdomain.com&relation=delegate_permission/common.handle_all_urls"

Command-Line Testing

iOS: xcrun and simctl

Test Universal Links on the iOS Simulator:

# Open a Universal Link in the Simulator
xcrun simctl openurl booted "https://yourdomain.com/products/123"

# If the app opens to the correct screen, the Universal Link is working
# If Safari opens instead, the AASA configuration is wrong

For real devices:

# Check AASA from the device's perspective (iOS 14+)
# On-device: Settings > Developer > Universal Links > Diagnostics
# Enter your domain to see if the AASA was downloaded successfully

Android: adb

Test App Links on a connected Android device or emulator:

# Open an App Link
adb shell am start -a android.intent.action.VIEW \
  -d "https://yourdomain.com/products/123" \
  -c android.intent.category.BROWSABLE

# Check if the app handles the URL
adb shell pm get-app-links com.your.package

# Verify App Links status
adb shell am compat enable 175408749 com.your.package  # Enable strict verification
adb shell pm verify-app-links --re-verify com.your.package
adb shell pm get-app-links com.your.package
# Look for: Status: verified

curl: Quick Verification Check

# Check AASA file
curl -sL -o /dev/null -w "%{http_code} %{content_type} %{url_effective}\n" \
  https://yourdomain.com/.well-known/apple-app-site-association

# Check assetlinks.json
curl -sL -o /dev/null -w "%{http_code} %{content_type} %{url_effective}\n" \
  https://yourdomain.com/.well-known/assetlinks.json

# Check for redirects (which break verification)
curl -sI https://yourdomain.com/.well-known/apple-app-site-association | grep -i location
# If this returns a Location header, there is a redirect, which is a problem

Browser-Based Testing

Notes App (iOS)

The simplest Universal Links test on iOS:

  1. Open the Notes app.
  2. Type or paste your deep link URL (e.g., https://yourdomain.com/products/123).
  3. Tap the link.
  4. If the app opens, Universal Links are working.
  5. If Safari opens, they are not.

Important: do not paste the link into Safari's address bar. Typing a URL directly into the address bar does not trigger Universal Links; it is treated as a navigation, not a link click.

Messages App (iOS)

Send yourself an iMessage with the deep link URL. Tapping it in Messages is one of the most reliable ways to trigger a Universal Link because Messages does not use an in-app browser.

Chrome (Android)

Type the deep link URL in Chrome's address bar on Android. If App Links are verified, the app should open automatically without a disambiguation dialog. If you see "Open with: Chrome or YourApp," the App Links verification may have failed.

Automated Testing

CI/CD Integration

Add deep link verification to your CI/CD pipeline:

# GitHub Actions example
name: Deep Link Verification
on:
  push:
    branches: [main]
  schedule:
    - cron: '0 */6 * * *'  # Every 6 hours

jobs:
  verify:
    runs-on: ubuntu-latest
    steps:
      - name: Check AASA
        run: |
          STATUS=$(curl -sL -o /dev/null -w "%{http_code}" \
            https://yourdomain.com/.well-known/apple-app-site-association)
          if [ "$STATUS" != "200" ]; then
            echo "AASA file returned $STATUS"
            exit 1
          fi

          CONTENT_TYPE=$(curl -sI \
            https://yourdomain.com/.well-known/apple-app-site-association \
            | grep -i content-type | tr -d '\r')
          if [[ ! "$CONTENT_TYPE" == *"application/json"* ]]; then
            echo "Wrong content-type: $CONTENT_TYPE"
            exit 1
          fi

      - name: Check assetlinks.json
        run: |
          STATUS=$(curl -sL -o /dev/null -w "%{http_code}" \
            https://yourdomain.com/.well-known/assetlinks.json)
          if [ "$STATUS" != "200" ]; then
            echo "assetlinks.json returned $STATUS"
            exit 1
          fi

      - name: Validate AASA JSON
        run: |
          curl -s https://yourdomain.com/.well-known/apple-app-site-association \
            | python3 -c "import json,sys; json.load(sys.stdin)" \
            || (echo "Invalid JSON in AASA" && exit 1)

Route Testing

Test that each deep link route resolves to the correct screen:

interface DeepLinkTestCase {
  url: string;
  expectedScreen: string;
  expectedParams: Record<string, string>;
}

const testCases: DeepLinkTestCase[] = [
  {
    url: 'https://yourdomain.com/products/abc123',
    expectedScreen: 'ProductDetail',
    expectedParams: { productId: 'abc123' }
  },
  {
    url: 'https://yourdomain.com/offers/summer-sale',
    expectedScreen: 'OfferDetail',
    expectedParams: { offerId: 'summer-sale' }
  },
  {
    url: 'https://yourdomain.com/referral/user456',
    expectedScreen: 'Referral',
    expectedParams: { referrerId: 'user456' }
  }
];

function testRouteResolution(testCases: DeepLinkTestCase[]) {
  for (const tc of testCases) {
    const result = resolveDeepLink(tc.url);
    assert(result.screen === tc.expectedScreen,
      `${tc.url}: expected ${tc.expectedScreen}, got ${result.screen}`);
    assert(deepEqual(result.params, tc.expectedParams),
      `${tc.url}: params mismatch`);
  }
}

Testing Checklist

Before Launch

Test iOS Android Desktop
AASA/assetlinks.json returns 200 Yes Yes N/A
No redirects on verification files Yes Yes N/A
App opens from Notes/Messages tap Yes N/A N/A
App opens from Chrome address bar N/A Yes N/A
Correct screen for each route Yes Yes N/A
Fallback page works Yes Yes Yes
In-app browser handling Yes Yes N/A
Deferred deep link (fresh install) Yes Yes N/A
Desktop shows web content + QR code N/A N/A Yes

After Each Deployment

Test Method
Verification files still accessible curl check in CI
App opens from a link Manual test or automated device test
No new routes missing from AASA Compare routes in code vs AASA paths
Analytics tracking fires on click Check analytics dashboard

Monthly

Test Method
Test on top 5 Android manufacturers Real devices (Samsung, Xiaomi, Huawei, Oppo, Pixel)
Test from major email clients Gmail, Outlook, Yahoo Mail
Test from social apps Instagram, Facebook, Twitter/X
Test deferred deep link end-to-end Fresh install from each source

Tolinku hosts your AASA and assetlinks.json files automatically, eliminating the most common configuration errors. Use the troubleshooting guide to diagnose issues.

For debugging specific problems, see debugging deep links: a step-by-step guide. For the complete deep linking guide, see the complete guide to deep linking in 2026.

Get deep linking tips in your inbox

One email per week. No spam.

Ready to add deep linking to your app?

Set up Universal Links, App Links, deferred deep linking, and analytics in minutes. Free to start.