Deferred deep links are harder to test than regular deep links. With a standard deep link, you tap a link, the app opens, and you see the result immediately. With a deferred deep link, you need an app store in the middle, a fresh install, and a matching process that depends on timing, network conditions, and device signals.
Most developers test the happy path and ship. This guide covers the happy path, but also the failure modes: what happens when IDFA is off, what happens when the install takes longer than expected, and what happens in an in-app browser.

Understanding What You're Testing
Deferred deep linking has three distinct phases, and each one can fail independently:
- Click capture: The user taps a link. The SDK records a fingerprint or device identifier and associates it with the link's destination parameters.
- Install: The user downloads and installs the app from the App Store or Google Play.
- Match: On first launch, the app SDK calls out to the matching service, retrieves the parameters from the pre-install click, and routes the user to the correct destination.
When testing, you need to verify each phase independently. A failure in phase one (no click recorded) looks identical to a failure in phase three (no match retrieved) from the user's perspective: they just open the app to the home screen. Logs from the SDK and the attribution dashboard tell you which phase failed.
For background on how the matching process works, see Tolinku's deferred deep linking guide.
Test Device Setup
iOS
A physical device is required for most deferred deep linking tests. The iOS Simulator does not support the App Store, so you cannot simulate a real install flow. Use TestFlight for your test builds.
Before each test:
- Reset Advertising Identifier: Go to Settings > Privacy & Security > Tracking. Toggle off "Allow Apps to Request to Track." This simulates a user who has denied ATT, which is important for testing probabilistic attribution.
- Sign out of iCloud (optional): This removes some signals used in fingerprinting, creating a stricter test environment.
- Delete the app completely: Long-press the app icon, select "Remove App." This clears all app data and resets the install state.
- Verify the app is gone: Open the App Store and confirm you can search for and "Get" the app (not "Open").
For deterministic attribution testing, you also want a device with ATT enabled. Run both scenarios: ATT granted and ATT denied.
Apple's ATT documentation covers what the framework exposes and what constitutes a consent-required tracking use case.
Android
Android testing has more flexibility. You can use a physical device or an emulator for some scenarios, but the Google Play install flow requires a physical device signed into a Google account.
Before each test:
- Reset Advertising ID: Go to Settings > Google > Ads > Reset advertising ID. On Android 12+, users can also opt out entirely; test both states.
- Uninstall the app: Settings > Apps > [Your App] > Uninstall. Confirm the app is removed.
- Clear Google Play cache (optional): Sometimes Play stores a cached install state. Settings > Apps > Google Play Store > Storage > Clear Cache.
Android's advertising ID documentation explains opt-out behavior from the developer perspective.
Simulating a Fresh Install
The hardest part of testing deferred deep links is that you need to go through a real install to test the matching phase. There is no shortcut that perfectly replicates production behavior. However, there are ways to make the loop faster.
TestFlight (iOS): Set up a TestFlight distribution. When testing, click your deferred link, then install from TestFlight. TestFlight installs behave like App Store installs for attribution purposes.
Internal App Sharing (Android): Google Play's Internal App Sharing lets you upload APKs and distribute them like Play Store installs. This is the closest Android equivalent to TestFlight for attribution testing.
Development builds with SDK bypass: Some SDKs let you simulate the deferred link match in a development build without going through the store. Tolinku's SDK supports a test mode that lets you trigger the match handler manually. See the SDK documentation for how to enable test mode.
The Test Flow
For each test run:
- Generate your deferred link (from your dashboard or via API).
- On the test device (with the app uninstalled), open the deferred link. Confirm the correct app store page opens.
- Install the app from the store.
- Launch the app.
- Check that the SDK callback fires with the correct parameters.
- Check the attribution dashboard and confirm the install is attributed to the correct link.
Time the gap between the click and the install. Attribution services set a fingerprint window, typically 24-72 hours. Test within the window. If you want to test the expiry case, wait longer than the configured window, then install and verify the user lands on the default destination rather than the deferred one.
Verifying Attribution Data
Attribution verification has two layers: the SDK callback in the app, and the server-side attribution record.
In-App Verification
Your SDK will provide a callback when the deferred link match is resolved. In Tolinku's iOS SDK, this looks like:
Tolinku.shared.onDeferredLink { params in
guard let destination = params["destination"] else { return }
// Navigate to destination
print("Deferred link params:", params)
}
In your test builds, log all parameters to the console. Verify that:
- The destination matches what you put in the link
- Any custom parameters (referral codes, campaign IDs, promo codes) are present and correct
- The callback fires exactly once, not multiple times
A common bug is the callback firing on every launch, not just the first. Verify that after the first launch, subsequent launches do not re-trigger the deferred link flow.
Dashboard Verification
Open your attribution analytics dashboard and check:
- The click event appears with the correct timestamp
- The install is attributed to the click
- The time-to-install is recorded
- The attribution method (deterministic vs. probabilistic) is logged
Tolinku's analytics dashboard shows all of this in the analytics view. If you're debugging a miss, the attribution log shows you exactly which signals were matched and which were absent.
Testing Edge Cases
No IDFA (ATT Denied)
This is the most common real-world failure mode on iOS. When IDFA is unavailable, the SDK falls back to probabilistic matching using IP address and device signals.
To test this scenario:
- Deny ATT on your test device (Settings > Privacy & Security > Tracking, toggle off all tracking).
- Run the full install flow.
- Verify the probabilistic match succeeds.
- Check the attribution record shows "probabilistic" as the match method.
If this test fails, you have a problem: a large fraction of your real iOS users will also fail to match.
In-App Browser Clicks
Links clicked inside Instagram, TikTok, LinkedIn, and similar apps open in an in-app browser. These browsers do not support Universal Links or App Links, which means the standard handoff mechanism fails.
Test this explicitly:
- Post your deferred link to an Instagram story or DM.
- Click the link from within the Instagram app.
- Verify the correct App Store page opens (or the correct web fallback).
- Install the app.
- Verify attribution matches.
In-app browsers often strip or modify cookies and headers, which affects fingerprinting. A good SDK handles this by adjusting the fingerprint collection to what's available in the embedded browser environment.
Slow or Interrupted Network
Attribution matching happens at first launch, which requires a network call. Test what happens when:
- The device is on a slow connection (3G)
- The network is unavailable at first launch
The app should still open successfully. The deferred link match should either retry when connectivity is restored or fail gracefully and send the user to the default home screen. It should never crash.
Time-to-Install Expiry
Set a link with a short fingerprint window (if your SDK allows it). Install the app after the window expires. Verify the user lands on the default destination and no spurious attribution is recorded.
Automated Testing
Manual testing every deferred link flow for every release is not practical. Automated testing fills the gap, though it has limits.
Unit Tests for the Callback Handler
The part of your code that responds to the deferred link match is fully unit-testable. Write tests that simulate different parameter payloads and verify the routing logic handles each one correctly:
func testDeferredLinkRoutesProductPage() {
let params: [String: String] = [
"destination": "/product/abc123",
"referrer": "campaign_spring_2026"
]
let router = DeferredLinkRouter()
let result = router.route(params: params)
XCTAssertEqual(result, AppRoute.product(id: "abc123"))
}
This won't test the network matching, but it will catch routing bugs that would otherwise require a full install cycle to discover.
Integration Tests with Mock SDK
If your SDK provides a test mode or mock object, use it in your integration test suite. Pass synthetic parameter payloads and verify end-to-end navigation without requiring a real network call or install.
CI/CD Considerations
For automated device testing, platforms like Xcode Cloud (iOS) and Firebase Test Lab (Android) support running tests on real devices. These can run your unit and integration tests on every pull request. Full deferred linking E2E tests (with actual store installs) are difficult to automate reliably and are usually reserved for manual QA before major releases.
Debugging Tips
When a test fails and you're not sure which phase went wrong, work backwards:
- Check the dashboard first. Did a click event get recorded? If not, the link was never opened or the SDK initialization failed.
- Check the install event. Did the install register? If yes but no match, the fingerprint failed to resolve.
- Check SDK logs. Enable verbose logging in your test build. The SDK will log what signals it collected, what it sent to the matching service, and what it received back.
- Check network traffic. Use a proxy tool like Charles or mitmproxy to inspect the SDK's network calls directly. Verify the request goes out and the response is non-empty.
- Check timing. Attribution windows are strict. A clock skew on the test device can cause misses that won't reproduce on production.
A methodical approach saves hours. Guessing at the failure mode leads to re-running the same test over and over without isolating the actual problem.
Summary
Testing deferred deep links properly takes more setup than other mobile testing scenarios, but the investment is worth it. Attribution failures are silent: users just land on the wrong screen. You won't know it's happening unless you test explicitly.
Cover the core flow, then cover the edge cases: ATT denied, in-app browsers, slow networks, and expired windows. Automate what you can at the unit and integration level, and do a full manual test before every major release.
Get deep linking tips in your inbox
One email per week. No spam.