{"id":1824,"date":"2026-07-23T09:00:00","date_gmt":"2026-07-23T14:00:00","guid":{"rendered":"https:\/\/tolinku.com\/blog\/?p=1824"},"modified":"2026-03-07T03:50:10","modified_gmt":"2026-03-07T08:50:10","slug":"deep-link-testing-tools","status":"publish","type":"post","link":"https:\/\/tolinku.com\/blog\/deep-link-testing-tools\/","title":{"rendered":"Best Deep Link Testing Tools and How to Use Them"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">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.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This guide covers tools and techniques for testing deep links. For debugging specific issues, see <a href=\"https:\/\/tolinku.com\/blog\/debugging-deep-links\/\">debugging deep links: a step-by-step guide<\/a>. For implementation, see <a href=\"https:\/\/tolinku.com\/blog\/implement-deep-links-from-scratch\/\">how to implement deep links from scratch<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Verification File Validators<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Apple App Site Association Validator<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Apple provides a validator for AASA files:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong><a href=\"https:\/\/search.developer.apple.com\/appsearch-validation-tool\/\" rel=\"nofollow noopener\" target=\"_blank\">App Search API Validation Tool<\/a><\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Enter your domain and the tool checks:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>AASA file is accessible at <code>\/.well-known\/apple-app-site-association<\/code><\/li>\n<li>Returns HTTP 200 (not a redirect)<\/li>\n<li>Valid JSON format<\/li>\n<li>Correct <code>content-type: application\/json<\/code> header<\/li>\n<li><code>applinks<\/code> section exists with valid app IDs<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">You can also check manually:<\/p>\n\n\n\n<pre><code class=\"language-bash\"># Fetch and validate AASA\ncurl -s https:\/\/yourdomain.com\/.well-known\/apple-app-site-association | python3 -m json.tool\n\n# Check headers\ncurl -sI https:\/\/yourdomain.com\/.well-known\/apple-app-site-association\n# Must return: content-type: application\/json (NOT text\/html or text\/plain)\n# Must return: HTTP 200 (NOT 301\/302 redirect)\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Google Digital Asset Links Validator<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Google provides a validator for assetlinks.json:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong><a href=\"https:\/\/developers.google.com\/digital-asset-links\/tools\/generator\" rel=\"nofollow noopener\" target=\"_blank\">Statement List Generator and Tester<\/a><\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Enter your domain and Android package name. The tool verifies:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>assetlinks.json<\/code> is accessible at <code>\/.well-known\/assetlinks.json<\/code><\/li>\n<li>File contains a valid statement linking the domain to the app<\/li>\n<li>Package name matches<\/li>\n<li>SHA-256 certificate fingerprint matches<\/li>\n<\/ul>\n\n\n\n<pre><code class=\"language-bash\"># Manual check\ncurl -s https:\/\/yourdomain.com\/.well-known\/assetlinks.json | python3 -m json.tool\n\n# Verify specific link\ncurl -s &quot;https:\/\/digitalassetlinks.googleapis.com\/v1\/statements:list?source.web.site=https:\/\/yourdomain.com&amp;relation=delegate_permission\/common.handle_all_urls&quot;\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Command-Line Testing<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">iOS: xcrun and simctl<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Test Universal Links on the iOS Simulator:<\/p>\n\n\n\n<pre><code class=\"language-bash\"># Open a Universal Link in the Simulator\nxcrun simctl openurl booted &quot;https:\/\/yourdomain.com\/products\/123&quot;\n\n# If the app opens to the correct screen, the Universal Link is working\n# If Safari opens instead, the AASA configuration is wrong\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">For real devices:<\/p>\n\n\n\n<pre><code class=\"language-bash\"># Check AASA from the device&#39;s perspective (iOS 14+)\n# On-device: Settings &gt; Developer &gt; Universal Links &gt; Diagnostics\n# Enter your domain to see if the AASA was downloaded successfully\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Android: adb<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Test App Links on a connected Android device or emulator:<\/p>\n\n\n\n<pre><code class=\"language-bash\"># Open an App Link\nadb shell am start -a android.intent.action.VIEW \\\n  -d &quot;https:\/\/yourdomain.com\/products\/123&quot; \\\n  -c android.intent.category.BROWSABLE\n\n# Check if the app handles the URL\nadb shell pm get-app-links com.your.package\n\n# Verify App Links status\nadb shell am compat enable 175408749 com.your.package  # Enable strict verification\nadb shell pm verify-app-links --re-verify com.your.package\nadb shell pm get-app-links com.your.package\n# Look for: Status: verified\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">curl: Quick Verification Check<\/h3>\n\n\n\n<pre><code class=\"language-bash\"># Check AASA file\ncurl -sL -o \/dev\/null -w &quot;%{http_code} %{content_type} %{url_effective}\\n&quot; \\\n  https:\/\/yourdomain.com\/.well-known\/apple-app-site-association\n\n# Check assetlinks.json\ncurl -sL -o \/dev\/null -w &quot;%{http_code} %{content_type} %{url_effective}\\n&quot; \\\n  https:\/\/yourdomain.com\/.well-known\/assetlinks.json\n\n# Check for redirects (which break verification)\ncurl -sI https:\/\/yourdomain.com\/.well-known\/apple-app-site-association | grep -i location\n# If this returns a Location header, there is a redirect, which is a problem\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Browser-Based Testing<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Notes App (iOS)<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The simplest Universal Links test on iOS:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Open the Notes app.<\/li>\n<li>Type or paste your deep link URL (e.g., <code>https:\/\/yourdomain.com\/products\/123<\/code>).<\/li>\n<li>Tap the link.<\/li>\n<li>If the app opens, Universal Links are working.<\/li>\n<li>If Safari opens, they are not.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">Important: do <strong>not<\/strong> paste the link into Safari&#39;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.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Messages App (iOS)<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">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.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Chrome (Android)<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Type the deep link URL in Chrome&#39;s address bar on Android. If App Links are verified, the app should open automatically without a disambiguation dialog. If you see &quot;Open with: Chrome or YourApp,&quot; the App Links verification may have failed.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Automated Testing<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">CI\/CD Integration<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Add deep link verification to your CI\/CD pipeline:<\/p>\n\n\n\n<pre><code class=\"language-yaml\"># GitHub Actions example\nname: Deep Link Verification\non:\n  push:\n    branches: [main]\n  schedule:\n    - cron: &#39;0 *\/6 * * *&#39;  # Every 6 hours\n\njobs:\n  verify:\n    runs-on: ubuntu-latest\n    steps:\n      - name: Check AASA\n        run: |\n          STATUS=$(curl -sL -o \/dev\/null -w &quot;%{http_code}&quot; \\\n            https:\/\/yourdomain.com\/.well-known\/apple-app-site-association)\n          if [ &quot;$STATUS&quot; != &quot;200&quot; ]; then\n            echo &quot;AASA file returned $STATUS&quot;\n            exit 1\n          fi\n\n          CONTENT_TYPE=$(curl -sI \\\n            https:\/\/yourdomain.com\/.well-known\/apple-app-site-association \\\n            | grep -i content-type | tr -d &#39;\\r&#39;)\n          if [[ ! &quot;$CONTENT_TYPE&quot; == *&quot;application\/json&quot;* ]]; then\n            echo &quot;Wrong content-type: $CONTENT_TYPE&quot;\n            exit 1\n          fi\n\n      - name: Check assetlinks.json\n        run: |\n          STATUS=$(curl -sL -o \/dev\/null -w &quot;%{http_code}&quot; \\\n            https:\/\/yourdomain.com\/.well-known\/assetlinks.json)\n          if [ &quot;$STATUS&quot; != &quot;200&quot; ]; then\n            echo &quot;assetlinks.json returned $STATUS&quot;\n            exit 1\n          fi\n\n      - name: Validate AASA JSON\n        run: |\n          curl -s https:\/\/yourdomain.com\/.well-known\/apple-app-site-association \\\n            | python3 -c &quot;import json,sys; json.load(sys.stdin)&quot; \\\n            || (echo &quot;Invalid JSON in AASA&quot; &amp;&amp; exit 1)\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Route Testing<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Test that each deep link route resolves to the correct screen:<\/p>\n\n\n\n<pre><code class=\"language-typescript\">interface DeepLinkTestCase {\n  url: string;\n  expectedScreen: string;\n  expectedParams: Record&lt;string, string&gt;;\n}\n\nconst testCases: DeepLinkTestCase[] = [\n  {\n    url: &#39;https:\/\/yourdomain.com\/products\/abc123&#39;,\n    expectedScreen: &#39;ProductDetail&#39;,\n    expectedParams: { productId: &#39;abc123&#39; }\n  },\n  {\n    url: &#39;https:\/\/yourdomain.com\/offers\/summer-sale&#39;,\n    expectedScreen: &#39;OfferDetail&#39;,\n    expectedParams: { offerId: &#39;summer-sale&#39; }\n  },\n  {\n    url: &#39;https:\/\/yourdomain.com\/referral\/user456&#39;,\n    expectedScreen: &#39;Referral&#39;,\n    expectedParams: { referrerId: &#39;user456&#39; }\n  }\n];\n\nfunction testRouteResolution(testCases: DeepLinkTestCase[]) {\n  for (const tc of testCases) {\n    const result = resolveDeepLink(tc.url);\n    assert(result.screen === tc.expectedScreen,\n      `${tc.url}: expected ${tc.expectedScreen}, got ${result.screen}`);\n    assert(deepEqual(result.params, tc.expectedParams),\n      `${tc.url}: params mismatch`);\n  }\n}\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Testing Checklist<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Before Launch<\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table>\n<thead>\n<tr>\n<th>Test<\/th>\n<th>iOS<\/th>\n<th>Android<\/th>\n<th>Desktop<\/th>\n<\/tr>\n<\/thead>\n<tbody><tr>\n<td>AASA\/assetlinks.json returns 200<\/td>\n<td>Yes<\/td>\n<td>Yes<\/td>\n<td>N\/A<\/td>\n<\/tr>\n<tr>\n<td>No redirects on verification files<\/td>\n<td>Yes<\/td>\n<td>Yes<\/td>\n<td>N\/A<\/td>\n<\/tr>\n<tr>\n<td>App opens from Notes\/Messages tap<\/td>\n<td>Yes<\/td>\n<td>N\/A<\/td>\n<td>N\/A<\/td>\n<\/tr>\n<tr>\n<td>App opens from Chrome address bar<\/td>\n<td>N\/A<\/td>\n<td>Yes<\/td>\n<td>N\/A<\/td>\n<\/tr>\n<tr>\n<td>Correct screen for each route<\/td>\n<td>Yes<\/td>\n<td>Yes<\/td>\n<td>N\/A<\/td>\n<\/tr>\n<tr>\n<td>Fallback page works<\/td>\n<td>Yes<\/td>\n<td>Yes<\/td>\n<td>Yes<\/td>\n<\/tr>\n<tr>\n<td>In-app browser handling<\/td>\n<td>Yes<\/td>\n<td>Yes<\/td>\n<td>N\/A<\/td>\n<\/tr>\n<tr>\n<td>Deferred deep link (fresh install)<\/td>\n<td>Yes<\/td>\n<td>Yes<\/td>\n<td>N\/A<\/td>\n<\/tr>\n<tr>\n<td>Desktop shows web content + QR code<\/td>\n<td>N\/A<\/td>\n<td>N\/A<\/td>\n<td>Yes<\/td>\n<\/tr>\n<\/tbody><\/table><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">After Each Deployment<\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table>\n<thead>\n<tr>\n<th>Test<\/th>\n<th>Method<\/th>\n<\/tr>\n<\/thead>\n<tbody><tr>\n<td>Verification files still accessible<\/td>\n<td>curl check in CI<\/td>\n<\/tr>\n<tr>\n<td>App opens from a link<\/td>\n<td>Manual test or automated device test<\/td>\n<\/tr>\n<tr>\n<td>No new routes missing from AASA<\/td>\n<td>Compare routes in code vs AASA paths<\/td>\n<\/tr>\n<tr>\n<td>Analytics tracking fires on click<\/td>\n<td>Check analytics dashboard<\/td>\n<\/tr>\n<\/tbody><\/table><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Monthly<\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table>\n<thead>\n<tr>\n<th>Test<\/th>\n<th>Method<\/th>\n<\/tr>\n<\/thead>\n<tbody><tr>\n<td>Test on top 5 Android manufacturers<\/td>\n<td>Real devices (Samsung, Xiaomi, Huawei, Oppo, Pixel)<\/td>\n<\/tr>\n<tr>\n<td>Test from major email clients<\/td>\n<td>Gmail, Outlook, Yahoo Mail<\/td>\n<\/tr>\n<tr>\n<td>Test from social apps<\/td>\n<td>Instagram, Facebook, Twitter\/X<\/td>\n<\/tr>\n<tr>\n<td>Test deferred deep link end-to-end<\/td>\n<td>Fresh install from each source<\/td>\n<\/tr>\n<\/tbody><\/table><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Tolinku for Deep Link Testing<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/tolinku.com\/features\/deep-linking\">Tolinku<\/a> hosts your AASA and assetlinks.json files automatically, eliminating the most common configuration errors. Use the <a href=\"https:\/\/tolinku.com\/docs\/troubleshooting\/common-issues\/\">troubleshooting guide<\/a> to diagnose issues.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For debugging specific problems, see <a href=\"https:\/\/tolinku.com\/blog\/debugging-deep-links\/\">debugging deep links: a step-by-step guide<\/a>. For the complete deep linking guide, see <a href=\"https:\/\/tolinku.com\/blog\/complete-guide-deep-linking-2026\/\">the complete guide to deep linking in 2026<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Test your deep links with confidence. Review the best tools for testing Universal Links, App Links, and deferred deep links on real devices.<\/p>\n","protected":false},"author":2,"featured_media":1823,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"rank_math_title":"Best Deep Link Testing Tools and How to Use Them","rank_math_description":"Test your deep links with confidence. Review the best tools for testing Universal Links, App Links, and deferred deep links on real devices.","rank_math_focus_keyword":"deep link testing tools","rank_math_canonical_url":"","rank_math_facebook_title":"","rank_math_facebook_description":"","rank_math_facebook_image":"https:\/\/tolinku.com\/blog\/wp-content\/uploads\/2026\/03\/og-deep-link-testing-tools.png","rank_math_facebook_image_id":"","rank_math_twitter_title":"","rank_math_twitter_description":"","rank_math_twitter_image":"https:\/\/tolinku.com\/blog\/wp-content\/uploads\/2026\/03\/og-deep-link-testing-tools.png","footnotes":""},"categories":[11],"tags":[25,23,20,75,24,189,80,22],"class_list":["post-1824","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-deep-linking","tag-android","tag-app-links","tag-deep-linking","tag-developer-tools","tag-ios","tag-quality-assurance","tag-testing","tag-universal-links"],"_links":{"self":[{"href":"https:\/\/tolinku.com\/blog\/wp-json\/wp\/v2\/posts\/1824","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/tolinku.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/tolinku.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/tolinku.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/tolinku.com\/blog\/wp-json\/wp\/v2\/comments?post=1824"}],"version-history":[{"count":1,"href":"https:\/\/tolinku.com\/blog\/wp-json\/wp\/v2\/posts\/1824\/revisions"}],"predecessor-version":[{"id":1825,"href":"https:\/\/tolinku.com\/blog\/wp-json\/wp\/v2\/posts\/1824\/revisions\/1825"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/tolinku.com\/blog\/wp-json\/wp\/v2\/media\/1823"}],"wp:attachment":[{"href":"https:\/\/tolinku.com\/blog\/wp-json\/wp\/v2\/media?parent=1824"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/tolinku.com\/blog\/wp-json\/wp\/v2\/categories?post=1824"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/tolinku.com\/blog\/wp-json\/wp\/v2\/tags?post=1824"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}