How to Test Delivery Tracking on Android (Complete Guide)
Delivery tracking is the visible heartbeat of any e‑commerce, food‑order, or logistics app. Users open the tracking screen to see where their package is, estimate arrival time, and decide whether they
Introduction: Why Delivery Tracking Is Critical
Delivery tracking is the visible heartbeat of any e‑commerce, food‑order, or logistics app. Users open the tracking screen to see where their package is, estimate arrival time, and decide whether they need to be home or redirect the shipment. When this screen fails—shows stale data, crashes, or hides essential controls—trust erodes instantly, leading to abandoned carts, negative reviews, and increased support load.
Testing tracking on Android is not a trivial UI check. The screen pulls data from multiple sources: a backend API, location services, push notifications, and sometimes a local cache. It must handle network flakiness, GPS drift, permission denials, and a variety of device configurations (screen sizes, Android versions, OEM customizations). A single missed edge case can produce a silent failure that only appears after the app has been in the wild for weeks.
This guide walks you through a complete testing strategy: from a concrete test matrix that covers happy paths, error paths, accessibility, and security, to manual procedures, automated scripts with Espresso/UI Automator and Appium, and finally how autonomous, persona‑driven exploration can surface bugs that scripted tests never consider.
Core Components of Delivery Tracking UI
Understanding what the tracking screen actually does helps you design meaningful tests. Typical Android tracking screens contain the following elements:
| UI Element | Typical Implementation | What It Represents |
|---|---|---|
| Toolbar with back button | androidx.appcompat.widget.Toolbar | Navigation back to order list |
| Order summary card | CardView with text and image | Order ID, items, total price |
| Map fragment | com.google.android.gms.maps.MapFragment or MapView | Live vehicle or package location |
| Status timeline | RecyclerView with custom item layout | Chronological steps (picked, in transit, out for delivery, delivered) |
| ETA badge | TextView with background color | Estimated time of arrival |
| Action buttons | MaterialButton (Call driver, Share tracking, Reschedule) | User‑initiated interactions |
| Progress indicator | CircularProgressIndicator or horizontal bar | Loading state while fetching updates |
| Error banner | LinearLayout with TextView shown on failure | Network or server error messages |
Each component can be a source of bugs. The map may fail to initialize if Google Play Services is out of date. The timeline may recycle views incorrectly, causing stale status text. The ETA badge may not update when the backend pushes a new estimate via Firebase Cloud Messaging.
When you write tests, treat each element as a testable unit and also consider their interactions (e.g., tapping the map should open a full‑screen map view).
Common Production Failures
Before diving into the test matrix, it helps to know what actually breaks in the field. The following failure patterns appear repeatedly across delivery‑tracking apps on Android:
- Stale map data – The map shows the last known location and never refreshes, often because the app stops listening to location updates after a background restriction.
- Missing ETA updates – The ETA badge stays at the initial value even though the server sends a newer estimate via push.
- Timeline duplication – After a device rotation, the
RecyclerViewshows duplicate entries because the adapter is not cleared before rebinding. - Permission‑related crashes – Targeting Android 13+ without requesting
ACCESS_FINE_LOCATIONat runtime leads to aSecurityExceptionwhen the map tries to access the user's location. - Dead action buttons – The “Call driver” button uses a
tel:intent but the app does not check if the dialer is available, causing anActivityNotFoundExceptionon tablets without telephony hardware. - Accessibility label missing – Icons in the timeline lack
contentDescription, making them invisible to TalkBack users. - Security leakage – The tracking screen logs the full order ID and customer address to Logcat, exposing personal data on rooted devices.
- Network‑switch glitch – Moving from Wi‑Fi to cellular causes a socket timeout that is not retried, leaving the UI stuck on a loading spinner.
- OEM‑specific theme clash – On devices with forced dark mode, the ETA badge text becomes unreadable because the app hard‑codes a light text color.
Knowing these patterns helps you prioritize test cases and craft realistic edge‑case scenarios.
Comprehensive Test Matrix
Below is a detailed matrix that groups test ideas by dimension (functional, error, edge, accessibility, security) and by scenario (happy path, error path, production‑only). Each row includes a short description, the expected result, and the suggested verification method.
| ID | Dimension | Scenario | Description | Expected Result | Verification |
|---|---|---|---|---|---|
| T1 | Functional | Happy path | User opens tracking after order placement; map shows current location, timeline shows “Order placed”, ETA shows realistic time. | All UI elements load within 2 s, no errors in Logcat. | Manual inspection + Espresso assertion on visibility and text. |
| T2 | Functional | Happy path | User taps “Share tracking”; system share sheet appears with pre‑filled text containing order ID and link. | Share intent fires, correct data in extras. | Espresso intents().intended(...) with hasExtra. |
| T3 | Functional | Error path | Backend returns 500 for location update; app shows error banner and retains last known data. | Error banner visible, map does not crash, timeline unchanged. | Mock server with WireMock, assert banner visibility. |
| T4 | Functional | Error path | User denies location permission; app prompts rationale and disables map. | Permission rationale dialog appears, map shows static placeholder, no crash. | Use adb shell pm revoke then launch activity, check dialog. |
| T5 | Edge | Network switch | Start on Wi‑Fi, simulate loss of connectivity, then restore on cellular. | App retries request, ETA updates after reconnection, no spinner stuck >10 s. | Use adb shell cmd connectivity to toggle, measure time with SystemClock. |
| T6 | Edge | Device rotation | Rotate device while timeline is mid‑animation. | Timeline state preserved, no duplicate items, map recenters correctly. | Espresso perform(rotate()), assert item count unchanged. |
| T7 | Edge | Low memory | Run app in background with memory‑intensive app, then return. | Tracking screen restores from saved instance state, no crash. | Use adb shell am kill after allocating memory via stress-ng. |
| T8 | Accessibility | WCAG 2.1 AA | All icons have contentDescription, color contrast ≥4.5:1, touch target ≥48dp. | TalkBack reads each element correctly, no overlapping touch areas. | Run Accessibility Scan Test (Espresso) or Android Studio Accessibility Scanner. |
| T9 | Accessibility | Font scaling | User sets system font size to 200 %. | All text scales, layouts do not truncate or overflow. | Change font size via Settings, assert text size via getTextSize(). |
| T10 | Security | Data leakage | No order ID, address, or token appears in Logcat or Crashlytics breadcrumbs. | Sensitive strings absent from logs. | Use adb logcat while performing actions, grep for patterns. |
| T11 | Security | Intent safety | “Call driver” uses implicit intent with Intent.ACTION_DIAL and resolves only if PackageManager.queryIntentActivities returns non‑empty. | Button disabled or shows toast on devices without telephony. | Query package manager, assert button enabled state. |
| T12 | Production‑only | GPS drift | Simulate GPS jitter using a mock location provider that jumps ±500 m every 2 s. | Map shows smooth movement, ETA recalculates without jumping backwards. | Use adb shell cmd location set-test-provider and feed mock NMEA. |
| T13 | Production‑only | Battery optimization | Device puts app in background restriction after 30 min of inactivity. | Tracking updates resume when user returns to foreground, no missed updates. | Use adb shell cmd appops set , then background the app. |
| T14 | Production‑only | OEM dark mode override | Force dark mode via developer options on a device that ignores app theme. | UI adapts, text remains readable, no hard‑coded colors break contrast. | Enable force dark, verify contrast with Accessibility Scanner. |
| T15 | Production‑only | Push notification delay | Server sends ETA update via FCM with 10‑second delay; app processes it even if in doze mode. | ETA badge updates after delay, no missed update. | Use adb shell cmd jobscheduler run -f to simulate. |
This matrix gives you a concrete starting point. You can expand each ID into a full test case with pre‑conditions, test data, and cleanup steps.
Manual Testing Procedure (Step‑by‑Step)
Even with automation, a disciplined manual pass catches nuance that scripts can miss, especially around gestures, sensor behavior, and OEM quirks. Follow this checklist for each build you intend to release to a internal test channel or production.
- Environment preparation
- Install the APK on a primary device (Pixel 8, Android 14) and at least two secondary devices representing different screen sizes and OEM skins (e.g., Samsung Galaxy A52, OnePlus Nord).
- Enable Developer options → Show taps, Pointer location, and Stay awake.
- Clear app data (
adb shell pm clear com.example.tracking) to start from a clean state.
- Happy‑path walkthrough
- Log in with a test account that has an active order.
- Navigate to Orders → Tap the most recent order → Verify the tracking screen loads.
- Confirm the toolbar shows the correct order ID and the back button works.
- Check the map: it should center on the device’s current location (or the last known location if GPS is off) and display a marker for the package.
- Scroll the timeline: each step should have a timestamp, an icon, and a short description.
- Verify the ETA badge shows a time in the future and updates after you manually trigger a location change (see step 4).
- Error‑path injection
- Turn off internet (
adb shell svc wifi disableandadb shell svc data disable). - Observe the error banner: it should appear within 3 s, the map should show a gray placeholder, and the timeline should retain the last successful data.
- Re‑enable connectivity and pull‑to‑refresh (if implemented) – the banner should disappear and fresh data load.
- Location and sensor simulation
- Open a terminal and send mock locations:
adb shell geo fix -122.4194 37.7749(San Francisco). - Watch the map marker move and the ETA adjust accordingly.
- Simulate a location denial:
adb shell pm revoke com.example.tracking android.permission.ACCESS_FINE_LOCATION. - Relaunch the tracking screen; the app should show a permission rationale and display a static map image.
- Interaction tests
- Tap the “Share tracking” button – ensure the share sheet appears with correct text.
- Tap the “Call driver” button on a device with telephony; verify the dialer opens with the driver’s number.
- On a tablet without telephony, confirm the button is either disabled or shows a toast indicating calling is not supported.
- Accessibility check
- Turn on TalkBack (
Settings → Accessibility → TalkBack). - Swipe through the screen; each element should announce a meaningful description.
- Pay special attention to map markers (they should announce “Package location, 2 km away”).
- Increase font size to 200 % and verify no clipping.
- Security sniff
- Connect the device to a workstation and run
adb logcat -v threadtime. - Perform a few actions (refresh, share, call).
- Search the log for the order ID, customer address, or any auth token. None should appear.
- OEM and theme validation
- On a Samsung device, enable “High contrast fonts” and verify readability.
- On a Xiaomi device, turn on “Miui Dark mode” and ensure the app respects it or provides its own dark theme.
- Battery‑optimization test
- Put the device in a battery‑optimization mode that restricts background (
Settings → Apps → Special access → Ignore battery optimizations →).→ Don’t allow - Leave the app in the background for 5 minutes, then bring it to foreground.
- Confirm that tracking resumes and no stale data is shown.
- Final sign‑off
- Take a screenshot of each major state (loading, error, success) and attach to the test report.
- Verify that the APK size did not increase unexpectedly (use
apkanalyzer).
Following these steps manually once per release candidate gives you confidence that the most obvious regressions are caught before they reach users.
Automated Testing with Android Espresso & UI Automator
Espresso excels at verifying UI state within your app’s process, while UI Automator reaches across system boundaries (e.g., permission dialogs, share sheets). Combining both gives you fast, reliable tests that run on every pull request.
Setting up the test module
Add the following dependencies to your app‑level build.gradle:
dependencies {
androidTestImplementation "androidx.test.espresso:espresso-core:3.5.1"
androidTestImplementation "androidx.test.espresso:espresso-intents:3.5.1"
androidTestImplementation "androidx.test.uiautomator:uiautomator:2.3.0"
androidTestImplementation "androidx.test:runner:1.5.2"
androidTestImplementation "androidx.test:rules:1.5.0"
}
Create a test class under src/androidTest/java/com/example/tracking/TrackingScreenTest.kt.
Happy‑path Espresso test
@RunWith(AndroidJUnit4::class)
class TrackingScreenTest {
@get:Rule
val intentsRule = IntentsTestRule(TrackingActivity::class.java)
@Test
fun `tracking loads and shows correct data`() {
// Assume a test order is pre‑loaded via a dependency‑injected fake repository
onView(withId(R.id.toolbar_title))
.check(matches(withText(containsString("ORDER #12345"))))
// Map fragment should be visible
onView(withId(R.id.map_fragment))
.check(matches(isDisplayed()))
// Timeline first item
onView(withId(R.id.recycler_timeline))
.check(matches(isDisplayed()))
onView(withId(R.id.recycler_timeline))
.perform(RecyclerViewActions.scrollToPosition<RecyclerView.ViewHolder>(0))
onView(withId(R.id.item_status_text))
.check(matches(withText(containsString("Order placed"))))
// ETA badge
onView(withId(R.id.eta_badge))
.check(matches(withText(matches(Pattern.compile("\\d{1,2}:\\d{2}\\s*(AM|PM)")))))
}
}
Error‑path with mocked server
Use WireMock or MockWebServer to return a 500 for the location endpoint.
@Test
fun `location error shows banner and does not crash`() {
// enqueue a 500 response
mockWebServer.enqueue(MockResponse()
.setResponseCode(500)
.setBody(""))
onView(withId(R.id.refresh_button))
.perform(click())
onView(withId(R.id.error_banner))
.check(matches(isDisplayed()))
onView(withId(R.id.map_fragment))
.check(matches(isDisplayed())) // map should not crash
}
UI Automator for system dialogs
When testing the location‑permission denial flow, you need to interact with the system permission dialog.
@Test
fun `location permission denied shows rationale`() {
// Revoke permission via ADB before launching
val uid = Runtime.getRuntime()
.exec("adb shell pm get-compat-mode com.example.tracking")
.inputStream
.readAllBytes()
.toString(Charsets.UTF_8.name())
launchActivity<TrackingActivity>()
val uiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
// Wait for the permission dialog
val allowButton = uiDevice.findObject(
UiSelector().text("Allow").className(android.widget.Button::class.java.name))
assertFalse(allowButton.exists()) // should not exist because we revoked
val rationale = uiDevice.findObject(
UiSelector().textContains("We need your location").className(android.widget.TextView::class.java.name))
assertTrue(rationale.exists())
}
Sharing intent verification
Espresso‑Intents lets you assert that the correct share intent was fired.
@Test
fun `share tracking sends correct data`() {
intending(toPackage("com.android.sharedreams")).respondWith(
InstrumentationResult.ActivityResult(Activity.RESULT_OK, null))
onView(withId(R.id.btn_share))
.perform(click())
intended(allOf(
hasAction(Intent.ACTION_SEND),
hasExtra(Intent.EXTRA_TEXT, startsWith("Check out my order #12345"))
))
}
Running the suite
Execute locally with Gradle:
./gradlew connectedAndroidTest # runs on all attached devices/emulators
For CI, configure Firebase Test Lab or GitHub Actions to spin up a matrix of devices (different API levels, screen sizes, OEM images).
Leveraging Appium for Cross‑Device Validation
While Espresso/UI Automator give you speed and deep‑in‑app assertions, Appium enables you to write the same tests in a language‑agnostic way and run them against real devices or emulators without recompiling the test APK. This is valuable for validating behavior across OEM firmware builds that may alter system dialogs or default apps.
Appium setup
- Install Node.js and the Appium server:
npm install -g appium
appium driver install uiautomator2
- Start the server:
appium --allow-insecure=chromedriver_autodownload
- Write a Java (or JavaScript) test using the Appium Java client.
import io.appium.java_client.android.AndroidDriver;
import io.appium.java_client.android.options.UiAutomator2Options;
import org.junit.*;
import org.openqa.selenium.*;
import org.openqa.selenium.support.ui.*;
public class TrackingAppiumTest {
private AndroidDriver driver;
private WebDriverWait wait;
@Before
public void setUp() throws Exception {
UiAutomator2Options options = new UiAutomator2Options()
.setPlatformName("Android")
.setAutomationName("UiAutomator2")
.setAppPackage("com.example.tracking")
.setAppActivity("com.example.tracking.TrackingActivity")
.setNoReset(true);
driver = new AndroidDriver(new URL("http://localhost:4723"), options);
wait = new WebDriverWait(driver, Duration.ofSeconds(10));
}
@Test
public void testEtaUpdatesAfterLocationChange() {
// Wait for tracking screen to load
WebElement eta = wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("eta_badge")));
String initialEta = eta.getText();
// Send a mock location via ADB (Appium can execute shell commands)
driver.executeScript("mobile: shell", ImmutableMap.of(
"command", "geo",
"args", List.of("-122.4194", "37.7749")));
// Wait for ETA to change (up to 15 seconds)
WebElement newEta = wait.until((WebDriver d) -> {
String text = driver.findElement(By.id("eta_badge")).getText();
return !text.equals(initialEta);
});
Assert.assertNotEquals(initialEta, newEta.getText());
}
@After
public void tearDown() {
if (driver != null) {
driver.quit();
}
}
}
Why Appium helps delivery‑tracking tests
- Cross‑OEM fidelity – You can run the same script on a Pixel, a Samsung, and a Xiaomi to confirm that the map fragment, timeline, and ETA badge behave identically despite vendor‑specific UI tweaks.
- Real‑device sensor injection – Using
mobile: shellyou can inject GPS coordinates, simulate network changes (cmd wifi,cmd data), or trigger battery‑optimization flags without needing to root the device. - Parallel execution – Appium grids (e.g., Sauce Labs, BrowserStack) let) allow you to run dozens of device configurations in parallel, shortening feedback cycles.
Example: Testing the “Call driver” button on a tablet
@Test
public void callDriverButtonIsDisabledOnTablet() {
boolean isPhone = driver.isDeviceLocked(); // placeholder; actual check via telephony manager
WebElement callBtn = driver.findElement(By.id("btn_call_driver"));
if (!isPhone) {
Assert.assertTrue(callBtn.getAttribute("enabled").equals("false"));
// Optionally verify a toast
WebElement toast = wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//android.widget.Toast")));
Assert.assertTrue(toast.getText().contains("Calling not supported"));
} else {
Assert.assertTrue(callBtn.isEnabled());
}
}
Appium tests are slower than Espresso (they traverse the UI hierarchy via the accessibility service), but they give you confidence that the app works on the actual hardware your customers use.
Accessibility and WCAG Checks for Tracking Screens
Accessibility is not a nice‑to‑have; it’s a legal requirement in many jurisdictions and directly impacts user satisfaction. Delivery‑tracking screens often contain custom views (map markers, timeline icons) that are easy to overlook.
Automated accessibility scanning with Espresso
Add the androidx.test.espresso:accessibility-checker dependency:
androidTestImplementation "androidx.test.espresso:accessibility-checker:3.5.1"
Then enable the checker in your test class:
@Before
fun enableAccessibilityChecks() {
AccessibilityChecks.enable()
}
Running any Espresso test will now automatically perform a scan after each action and fail if violations are found (e.g., missing contentDescription, insufficient contrast).
Manual verification checklist
| Check | How to test | Pass criteria |
|---|---|---|
| ContentDescription on icons | Enable TalkBack, swipe to each timeline icon | Each icon announces a meaningful phrase (e.g., “Out for delivery, truck icon”). |
| Color contrast | Use Android Studio’s Accessibility Scanner or a contrast‑checking app | Text vs. background ratio ≥ 4.5:1 for normal text, ≥ 3:1 for large text. |
| Touch target size | Enable “Show layout bounds” in Developer options | Every interactive element (buttons, map markers) occupies at least 48 dp × 48 dp. |
| Scalable fonts | Increase system font size to 200 % | No text is clipped, layouts reflow or scroll as needed. |
| Screen reader navigation order | TalkBack linear navigation | Focus moves logically from toolbar → order summary → map → timeline → action buttons. |
| Accessible error messages | Trigger a network failure | Error banner is announced and describes the problem and possible recovery steps. |
Fixing common issues
- Map markers – Wrap the marker view in a
FrameLayoutwith an invisibleTextViewthat holds the description, then useGoogleMap.setInfoWindowAdapterto supply a custom view that includes the description ascontentDescription. - Custom timeline icons – If you use
ImageViewfor status icons, always setandroid:contentDescription="@string/status_picked"(or retrieve from a string resource based on the enum). - Contrast – Avoid hard‑coding colors; define them in a theme and use the
?attr/colorOnSurfacefor text on surfaces. Run the app in night mode to verify both light and dark themes.
Security and Privacy Considerations
Delivery tracking inevitably exposes personal data: order ID, customer name, delivery address, and sometimes payment token. A breach or inadvertent leak can lead to fraud, identity theft, or regulatory penalties (GDPR, CCPA).
Data‑in‑transit
- Ensure all API calls use HTTPS with TLS 1.2 or higher.
- Pin the server certificate or use
NetworkSecurityConfigwithto prevent man‑in‑the‑middle attacks in development builds. - Verify that the app does not fall back to clear‑text HTTP even when the user toggles “Allow insecure connections” in developer options (a common debugging leftover).
Data‑at‑rest
- Cache only non‑PII (e.g., order status codes) in
SharedPreferencesor Room. - If you must store the address temporarily, encrypt it with a key derived from the device’s hardware-backed keystore (
AndroidKeyStore). - Clear caches on logout or when the user explicitly deletes their data.
Logging
- Never log full addresses, order IDs, or auth tokens. Use a wrapper like
Timberwith a custom tree that redacts known PII patterns. - In production builds, set
loggabletofalsein the manifest (android:debuggable="false").
Permissions
- Request
ACCESS_FINE_LOCATIONonly when the tracking screen is visible; release it inonPause()to reduce background exposure. - Provide a clear rationale string that explains why location is needed (e.g., “To show your package’s live location on the map”).
Testing for leaks
Use adb logcat combined with grep to search for known patterns:
adb logcat -v threadtime | grep -E "(order|address|token|password)"
If any line returns a match, investigate the logging call and replace it with a redacted version.
Dynamic analysis tools like MobSF or the Android Studio Data Safety section can also surface hard‑coded strings or insecure HTTP usage.
Edge Cases That Appear Only in Production
Even the most exhaustive test matrix can miss issues that only surface under real‑world user conditions. Below are several production‑only phenomena that have caused outages in delivery‑tracking apps, along with tactics to surface them earlier.
| Phenomenon | Why it hides in lab | Detection strategy |
|---|---|---|
| GPS drift under urban canyon | Indoor tests get a stable fix; outdoors, multipath causes jumps. | Use a GPS spoofing app (e.g., Fake GPS Go) to inject jitter ±30 m every second while the app is foreground. Observe map smoothness and ETA stability. |
| Background location throttling | Test devices often have battery optimization disabled. | Enable “Background location limits” (Settings → Location → Advanced → Background location limits) and verify that location updates still arrive via a foreground service. |
| Push notification doze delays | Emulators deliver FCM instantly. | Force doze mode (adb shell dumpsys deviceidle force-idle) then send an FCM payload; measure latency between send and UI update. |
| Carrier‑specific SMS OTP interception | Some carriers block or delay SMS; test environments use virtual numbers. | Use a real SIM from a problematic carrier (identified via field‑monitoring) and simulate delayed delivery via a proxy that holds the SMS for 10‑15 s before forwarding. |
| OEM‑specific aggressive RAM management | Test devices have plenty of free RAM. | Install a memory‑stress app (e.g., com.github.ksk0013.RamBooster) that constantly allocates and frees large chunks, then launch the tracking app and verify it recovers from a low‑memory kill without losing state. |
| Network handover stalls (Wi‑Fi → LTE → 5G) | Lab networks are static. | Use a network emulator like clumsy or tc on a Linux router to inject latency spikes and packet loss during handover, then check that the app retries with exponential backoff and does not show a perpetual spinner. |
| Multilingual layout breakage | QA often tests only en‑US. | Change device language to Arabic or Hebrew (RTL) and ensure the toolbar, timeline, and map controls mirror correctly. |
| Accessibility service interference | TalkBack may be off in test builds. | Enable TalkBack, Switch Access, or a third‑party accessibility service and confirm that all gestures (double‑tap, swipe) still work as expected. |
To catch these earlier, incorporate production‑like test harnesses into your CI:
- Deploy a staging environment that mirrors the production CDN, uses real FCM keys, and has a network latency injector (e.g.,
toxiproxy). - Run a nightly suite on a device farm with a rotation of SIM cards from different carriers.
- Use chaos engineering principles: periodically kill the app’s process, disable GPS, or toggle airplane mode mid‑flow and assert graceful recovery.
Autonomous, Persona‑Driven Exploration (Mentioning SUSA)
Scripted tests verify that the app behaves as you expect, but they cannot anticipate the myriad ways real users interact with a feature. Autonomous testing platforms that simulate diverse user personas can surface bugs hidden in edge‑case flows, unexpected gesture combinations, or accessibility‑driven navigation patterns that a scripted tester would never think to write.
One such platform is SUSA, an autonomous QA agent that you point at an APK or a web URL. After you upload the tracking‑app build, SUSA explores the application without any pre‑written scripts, using a set of built‑in personas:
- Curious – taps every visible element, long‑presses icons, tries to drag the map.
- Impatient – rapidly presses refresh, spams the back button, and attempts to shortcut flows.
- Novice – follows only the most obvious cues, often missing hidden gestures.
- Adversarial – injects malformed inputs, tries to break the map with rapid coordinate changes, and attempts to invoke hidden developer options.
- Elderly
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