How to Test Settings Page on Android (Complete Guide)
The settings screen is often the most frequently accessed part of an Android application after the main UI. Users reach it to change notification preferences, manage accounts, toggle privacy controls,
Why the Settings Page Deserves Dedicated Testing
The settings screen is often the most frequently accessed part of an Android application after the main UI. Users reach it to change notification preferences, manage accounts, toggle privacy controls, adjust language, or clear data. Because it aggregates many disparate functions—some of which interact with system services, shared preferences, or remote APIs—a defect here can have cascading effects: a mis‑saved preference might disable push notifications for all users, a poorly handled intent could launch an inaccessible system screen, or a race condition while writing to SharedPreferences might corrupt user data and trigger a crash on the next launch. In production, settings‑related bugs are notorious for slipping through functional test suites that focus on core flows, yet they generate a disproportionate share of support tickets and negative reviews. Dedicated testing therefore protects both reliability and user trust.
Common Failure Modes Seen in Production
Observations from crash reports, ANR logs, and user feedback reveal a repeatable set of problems that manifest specifically on settings screens:
| Failure Category | Typical Symptom | Root Cause |
|---|---|---|
| Preference Persistence | Toggle reverts after app restart | Incorrect SharedPreferences commit/apply, missing MODE_PRIVATE, or asynchronous write not awaited |
| Intent Mis‑routing | Opening “Notifications” launches a blank activity or crashes | Wrong action string, missing permission, or using startActivity without checking resolveActivity |
| UI State Drift | Switch shows ON but underlying value is OFF | Binding logic only updates UI on init, not on listener callbacks |
| Accessibility Breakage | TalkBack skips a switch or reads incorrect label | Missing contentDescription, reliance on visual-only cues, or improper focus order |
| Security Leak | Debug settings exposed to production builds | Feature flag not stripped, or settings activity exported without protection |
| Resource Exhaustion | Scrolling a long list causes OOM or jank | Loading all preference items into memory at once, or using heavy layouts in RecyclerView items |
| Locale / Layout Issues | Text overlaps or truncates in right‑to‑left languages | Hard‑coded dimensions, not using wrap_content or weight, or missing alternative resources |
These patterns help shape a test matrix that goes beyond “does the switch change?” and probes the interactions that cause real‑world harm.
Building a Comprehensive Test Matrix
A matrix organizes test ideas by dimension (what we test) and variant (how we test it). Below is a master table that can be copied into a test‑management tool or used as a checklist for manual runs. Each row represents a distinct test case; columns indicate the category, the specific condition, the expected outcome, and notes on automation feasibility.
| ID | Category | Test Condition | Expected Result | Automation Hint | |
|---|---|---|---|---|---|
| H1 | Happy Path | Navigate to Settings from main screen via action bar icon | Settings activity launches, title visible | UI Automator waitForExists on toolbar title | |
| H2 | Happy Path | Toggle a switch (e.g., “Enable notifications”) ON | Switch shows ON, underlying preference stored as true | Espresso onView(withId(R.id.switch_notifications)).perform(click()) | |
| H3 | Happy Path | Toggle same switch OFF | Switch shows OFF, preference stored as false | Same as H2, assert false | |
| H4 | Happy Path | Enter text in an EditText preference (e.g., “Server URL”) and save | Text persists after leaving and returning to screen | Espresso typeText + closeSoftKeyboard + assert on preference | |
| H5 | Happy Path | Open a sub‑screen via preference (e.g., “Account settings”) | New activity/fragment opens, back button returns | UI Automator click() on preference, then pressBack() | |
| E1 | Error Path | Attempt to save an empty string in a required EditText | Validation error displayed, preference unchanged | Espresso typeText("") then pressEnter, check for error TextView | |
| E2 | Error Path | Enter a URL with illegal characters (e.g., “http://<script>”) | Input rejected or sanitized, no crash | Same as E1, verify no exception in logcat | |
| E3 | Error Path | Launch a settings intent that resolves to no activity (e.g., malformed action) | App shows a toast or graceful fallback, no crash | Use adb shell am start -a "android.settings.BOGUS" and monitor | |
| E4 | Error Path | Rapidly toggle a switch 50 times in 5 seconds | UI remains responsive, preference ends in last state | UI Automator loop with performClick() and Thread.sleep(50) | |
| E5 | Error Path | Change language to a locale lacking alternative resources (e.g., “zz-ZZ”) | App falls back to default language, layout intact | Use adb shell setprop persist.sys.language zz then relaunch | |
| X1 | Edge Case | Rotate device while a preference dialog is open | Dialog retains state, no leak | UI Automator setOrientationLeft() then assert dialog visibility | |
| X2 | Edge Case | Minimize app (Home) while a SettingsFragment is visible, then restore | Fragment state restored, no duplicate instances | adb shell am home then adb shell am start -n com.example/.SettingsActivity | |
| X3 | Edge Case | Navigate to Settings from a deep link that passes extra parameters | Extras ignored or handled safely, UI shows correct default | Launch via adb shell am start -d "myapp://settings?foo=bar" | |
| X4 | Edge Case | System dark mode toggled while Settings is in foreground | UI updates to match new theme instantly | adb shell cmd uimode night yes/no and assert colors | |
| X5 | Edge Case | Low memory simulation (via adb shell am send-trim-memory com.example MODERATE) | Settings screen continues to function, no OOM | Monitor logcat for LowMemoryKill | |
| A1 | Accessibility | TalkBack navigation order follows visual order | Focus moves sequentially through each preference | Use Accessibility Test Framework (ATF) or manual TalkBack swipe | |
| A2 | Accessibility | Every switch has a contentDescription that conveys state | TalkBack reads “Switch, notifications, on” or “off” | Espresso check(matches(withContentDescription(containsString("notifications")))) | |
| A3 | Accessibility | Contrast ratio of text vs background ≥ 4.5:1 for normal text | Meets WCAG AA | Use Android Studio’s Layout Inspector or external contrast checker | |
| A4 | Accessibility | Touch target size ≥ 48dp for all interactive elements | Meets Android accessibility guidelines | UI Automator getBounds() and compute width/height | |
| S1 | Security | Settings activity not exported (android:exported="false" in manifest) | Other apps cannot launch it via intent | `adb shell pm dump com.example | grep SettingsActivity` |
| S2 | Security | No debug‑only preferences visible in production build | Only production‑relevant items appear | Compare UIAutomator dump of debug vs release APK | |
| S3 | Security | Attempt to inject JavaScript into a WebView‑based preference (if any) | No script execution, input sanitized | Use adb shell am start -n com.example/.WebViewPreference then send JS via WebView.evaluateJavascript (expect no alert) | |
| S4 | Privacy | Clearing app data from Settings → Apps → [YourApp] → Storage clears all preferences | After relaunch, all preferences revert to defaults | adb shell pm clear com.example then verify defaults | |
| S5 | Privacy | Biometric toggle (if present) respects system lockout after failed attempts | After 5 failed attempts, toggle disabled or prompts fallback | Use adb shell cmd biometric_weak set and observe |
The table above can be filtered by category to generate focused test suites (e.g., run all A* tests in an accessibility regression). Each hint column suggests the most straightforward automation approach, but many cases benefit from a combination of tools (UI Automator for navigation, Espresso for assertion, adb for system‑state manipulation).
3.1 Happy‑Path Scenarios
Happy‑path tests confirm that the primary user flow works without obstruction. They form the baseline for any regression suite. Typical steps include launching the settings screen from multiple entry points (navigation drawer, action bar, deep link), interacting with each preference type (switch, checkbox, radio button, EditText, list preference), and verifying that the UI reflects the underlying model instantly. Because settings often act as a hub, happy‑path tests also check that returning to the main UI does not leave stray fragments in the back stack—a common source of memory leaks.
3.2 Error‑Path and Validation Scenarios
Error paths probe how the settings UI handles invalid input, missing resources, or unexpected system states. This includes boundary values for numeric preferences, malformed URIs, empty required fields, and intents that cannot be resolved. A robust settings screen should never crash; instead, it must display a clear inline error, toast, or snackbar and leave the persisted state unchanged. Logging is also important: developers should verify that no stack traces appear in logcat when these conditions are exercised.
3.3 Edge‑Case and Stress Scenarios
Edge cases exercise the settings screen under atypical but possible conditions: configuration changes (rotation, locale, font scale), multitasking (app in background while a dialog is open), low‑memory situations, and rapid user interaction. Stress tests—such as toggling a switch dozens of times in a short window—reveal problems with debouncing, thread safety, or excessive layout passes. Simulating low memory via adb shell am send-trim-memory helps uncover allocations that are only problematic when the system pressures the app.
3.4 Accessibility (WCAG) Checks
Accessibility testing ensures that users relying on assistive technologies can perceive, operate, and understand the settings. Key checks include focus order, labeling of interactive elements, sufficient color contrast, and appropriately sized touch targets. Automated tools like the Accessibility Test Framework (ATF) can be integrated into unit tests, while manual verification with TalkBack and Switch Access remains essential for nuanced issues such as ambiguous descriptions or hidden controls.
3.5 Security and Privacy Checks
Settings often expose toggles that affect data sharing, logging, or debug features. Security tests confirm that the activity is not inadvertently exported, that debug‑only preferences are stripped in release builds, and that any WebView‑based settings sanitize input to prevent script injection. Privacy tests verify that clearing app data through system settings truly removes all persisted preferences and that biometric or credential toggles respect platform lockout policies.
Manual Testing Procedure – Step‑by‑Step
Even with automation in place, a manual exploratory pass catches issues that scripted checks miss—especially those tied to device‑specific OEM skins, custom themes, or unexpected system dialogs. Below is a repeatable manual workflow that a QA engineer can follow before each release.
4.1 Preparation (Device, Emulator, Logcat)
- Select a matrix of devices covering different API levels (e.g., 21, 28, 30, 33), screen sizes, and manufacturers (Google Pixel, Samsung OnePlus, Xiaomi). If using emulators, create AVDs with Play Store enabled to test Google‑services‑dependent preferences.
- Enable developer options: USB debugging, “Show taps”, “Stay awake while charging”, and “Don’t keep activities”.
- Set up logcat capture:
adb logcat -v threadtime > settings_test_$(date +%F_%H%M).txt. Filter withadb logcat | grep -i settingsto reduce noise. - Install the build:
adb install -r app-release.apk. For debug builds, add-gto grant all runtime permissions at install time. - Clear previous state (optional but recommended):
adb shell pm clear com.example. This guarantees a clean preference set.
4.2 Navigation and State Setup
- Launch the app via launcher icon or
adb shell monkey -p com.example -c android.intent.category.LAUNCHER 1. - Navigate to Settings using the most common entry point (e.g., action bar overflow → Settings). Note the time taken; >2 seconds may indicate heavy work on the UI thread.
- Verify the toolbar title and that the up arrow (if present) returns to the previous screen.
- Check initial state of a few key preferences (switches, text fields) against known defaults (often stored in
res/xml/preferences.xml).
4.3 Executing the Matrix
Proceed through the test matrix in logical groups:
| Sub‑step | Action | Observation |
|---|---|---|
| Switch toggles | Tap each switch, observe immediate UI change, then leave screen and return to confirm persistence. | UI updates instantly; preference stored correctly. |
| Text fields | Tap EditText, type valid data, dismiss keyboard, press Save (if present), navigate away and back. | Text appears unchanged after return. |
| List preferences | Tap entry, select an option from dialog, confirm selection reflected in summary. | Summary updates, underlying value stored. |
| Sub‑screens | Tap preference that launches another Activity/Fragment, verify new screen title, use back to return. | New screen loads, back stack behaves correctly. |
| Error injection | For each EditText, attempt invalid input (empty, too long, illegal chars). | Inline error appears, no crash, preference unchanged. |
| System state change | Rotate device, change font size, toggle dark mode, simulate low memory. | UI adapts, no loss of state, no leaks. |
| Accessibility walk‑through | Enable TalkBack, swipe through each element, listen to descriptions. | Every element announces purpose and state correctly. |
| Security check | Attempt to launch Settings activity from another app via adb shell am start -n com.example/.SettingsActivity. | If exported false, launch fails with Permission denied; if true, ensure no sensitive data shown. |
During each step, keep logcat visible. Look for lines containing AndroidRuntime, ANR, StrictMode, or NullPointerException. Capture screenshots of any unexpected UI (e.g., overlapped text, missing icons) using adb exec-out screencap -p > screen.png.
4.4 Observing and Recording Results
Use a simple spreadsheet with columns: Test ID, Device, OS, Result (Pass/Fail/Issue), Notes, Attachments (screenshot/log snippet). For failures, include:
- Exact steps to reproduce (including any device‑specific setting like “Developer options → Show layout bounds”).
- Logcat excerpt (timestamp ± 500 ms).
- Impact assessment (e.g., “causes notification toggle to revert, affecting all users”).
- Severity (Critical, High, Medium, Low) based on user impact and reproducibility.
After the pass, triage issues: assign to developers, add regression tests for any automated gaps, and update the test matrix if new failure modes emerge.
Automated Testing with Android‑Specific Tools
Automation turns the manual matrix into repeatable checks that run on every commit. Android offers a layered tooling stack; choosing the right layer for each test case reduces flakiness and speeds up feedback.
5.1 UI Automator Basics
UI Automator operates at the system level, making it ideal for cross‑app interactions and for verifying that intents resolve correctly. A minimal test class looks like this:
@RunWith(AndroidJUnit4.class)
public class SettingsUiAutomatorTest {
private UiDevice device;
@Before
public void setUp() {
device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
// Ensure we start from home screen
device.pressHome();
}
@Test
public void launchSettingsFromHome() {
// Open app drawer, locate Settings icon by text
UiObject2 apps = device.findObject(By.clazz("android.widget.FrameLayout")
.desc("Apps"));
apps.click();
UiObject2 settingsIcon = device.findObject(By.text("Settings"));
settingsIcon.click();
// Verify Settings activity is in foreground
assertTrue(device.wait(Until.hasObject(By.pkg("com.example.settings")
.depth(0)), 5000));
}
}
Key points:
- Use
UiObject2(introduced in API 26) for richer gestures and built‑in waiting. - Avoid hard‑coded coordinates; rely on resource IDs or text descriptors when possible.
- After each test, call
device.pressBack()until home to reset state.
5.2 Espresso for Settings Fragments
When the settings screen is implemented as a Fragment or uses PreferenceFragmentCompat, Espresso provides fast, deterministic UI tests within the app process. Example for a switch preference:
@RunWith(AndroidJUnit4.class)
public class SettingsEspressoTest {
@Rule
public ActivityTestRule<SettingsActivity> activityRule =
new ActivityTestRule<>(SettingsActivity.class, false, false);
@Test
public void toggleNotificationsSwitch() {
// Launch activity with a clean intent
Intent intent = new Intent();
activityRule.launchIntent = intent;
activityRule.launchActivity();
// Locate switch by id (defined in preference layout)
onView(withId(R.id.switch_notifications))
.check(matches(isNotChecked())) // default off
.perform(click())
.check(matches(isChecked()));
// Verify underlying SharedPreferences
Context context = InstrumentationRegistry.getInstrumentation()
.getTargetContext();
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
assertTrue(prefs.getBoolean("notifications_key", false));
}
}
Espresso shines for:
- Rapid execution (sub‑second per test).
- Precise assertions on view state and underlying data.
- Integration with AndroidJUnitRunner and Gradle’s
connectedAndroidTest.
5.3 Using UiAutomatorViewer and Layout Inspector
Before writing selectors, inspect the view hierarchy:
- UiAutomatorViewer:
adb shell uiautomator dump /data/local/tmp/view.xml && adb pull /data/local/tmp/view.xml . && uiautomatorviewer. - Layout Inspector (Android Studio): Run the app, then
View → Layout Inspector. It shows live hierarchy, resource IDs, and allows you to copy XPath‑like selectors.
These tools reduce the chance of brittle selectors that break after a minor layout tweak.
5.4 Data‑Driven Tests with JUnit‑Parameterized
Many preference types share the same test pattern (enter value, verify persistence). Use JUnit’s Parameterized runner to feed a matrix of inputs:
@RunWith(Parameterized.class)
public class EditTextPreferenceTest {
@Parameterized.Parameters
public static Collection<Object[]> data() {
return Arrays.asList(new Object[][] {
{ "https://api.example.com", true },
{ "", false }, // empty should be rejected
{ " ", false }, // whitespace only
{ "http://<script>alert(1)</script>", false }
});
}
private String input;
private boolean expectedValid;
public EditTextPreferenceTest(String input, boolean expectedValid) {
this.input = input;
this.expectedValid = expectedValid;
}
@Test
public void testEditTextPreference() {
onView(withId(R.id.edittext_server_url))
.perform(clearText(), typeInput(input), closeSoftKeyboard());
if (expectedValid) {
onView(withId(R.id.edittext_server_url))
.check(matches(withInputText(input)));
// verify persisted value
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(
InstrumentationRegistry.getTargetContext());
assertEquals(input, prefs.getString("server_url_key", ""));
} else {
// expect error TextView to appear
onView(withId(R.id.input_error))
.check(matches(isDisplayed()));
// value should remain unchanged
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(
InstrumentationRegistry.getTargetContext());
assertNotEquals(input, prefs.getString("server_url_key", ""));
}
}
}
This approach guarantees that each variant is exercised and makes adding new test cases as simple as extending the data array.
5.5 Handling System Settings Intents
Some preferences launch built‑in Android settings (e.g., “Notification access”, “Battery optimization”). Testing these requires verifying that the correct intent is fired and that the app handles the result gracefully when the user cancels or does not grant permission.
@Test
public void launchNotificationAccessSettings() {
// Mock the intent resolution to avoid leaving the test app
Intent intended = new Intent(Settings.ACTION_NOTIFICATION_LISTENER_SETTINGS);
intending(toPackage("com.android.settings")).respondWith(
new Instrumentation.ActivityResult(Activity.RESULT_CANCELED, null));
onView(withId(R.id.pref_notification_access))
.perform(click());
// Verify that our app shows a toast or snackbar indicating the outcome
onView(withText("Notification access not granted"))
.inRoot(isToast())
.check(matches(isDisplayed()));
}
Using Intents from androidx.test.espresso.intent ensures we stay within the test process while still validating the intent construction.
5.6 Flaky‑Test Mitigation Strategies
Settings tests can become flaky due to animations, async preference writes, or system dialogs. Mitigation tactics include:
- Disable animations on test devices:
adb shell settings put global window_animation_scale 0.0 && adb shell settings put global transition_animation_scale 0.0 && adb shell settings put global animator_duration_scale 0.0. - Explicit Idling Resources for asynchronous writes: register an
SharedPreferences.Editor.apply()call can be wrapped in a customIdlingResourcethat Espresso waits on. - Use
UiDevice.waitForIdle()after UI Automator actions to let the system settle. - Limit test scope: run UI Automator tests on a separate Gradle task (
connectedAndroidTestUiAutomator) to avoid interfering with Espresso’s activity lifecycle. - Capture screenshots on failure via a TestRule that calls
DeviceScreenshot.take()and attaches them to the test report.
Applying these practices consistently yields a settings test suite that runs in under two minutes on a typical CI agent and provides high confidence that regressions are caught early.
Leveraging Autonomous, Persona‑Driven Exploration (SUSA mention)
Scripted tests excel at verifying known conditions, but they rarely venture into the unexplored corners of a settings screen where real users behave unpredictably. Autonomous exploration platforms like SUSA supplement manual and automated efforts by simulating diverse user personalities and learning from each run.
6.1 How Persona Profiles Influence Navigation
SUSA defines behavior models for personas such as:
- Impatient – taps rapidly, skips long‑press gestures, abandons screens after two seconds of inactivity.
- Curious – taps every visible element, opens sub‑menus, tries long‑press on icons to see hidden actions.
- Novice – relies on default flows, avoids advanced options, often misses contextual help.
- Accessibility – uses TalkBack or Switch Access exclusively, navigates via linear sweep.
- Adversarial – attempts to input malformed data, inject scripts, or trigger system intents with unexpected extras.
When pointed at an APK or a URL, SUSA’s engine launches the app, identifies the settings entry point, and then drives the UI according to the selected persona’s policy. Each interaction is logged, and the platform builds a map of visited screens, dead ends, and encountered exceptions.
6.2 Example: Finding a Hidden Dead‑Button via Impatient Persona
In one test run, the Impatient persona repeatedly tapped the “Advanced” header in a SettingsPreferenceScreen after the associated spinner failed to populate within 800 ms. The rapid taps caused the underlying RecyclerView to recycle a view holder while its adapter was still loading data, resulting in a NullPointerException that crashed the app. The stack trace, captured automatically by SUSA, pointed to a missing null‑check in the onBindViewHolder method—a scenario that would never appear in a scripted test that waits for the spinner to finish.
The platform then generated a regression script:
// SUSA‑generated Appium test (Android)
@Test
public void testAdvancedHeaderRapidTap() {
driver.findElement(By.id(R.id.header_advanced)).click();
// Simulate impatient double‑tap within 300ms
driver.findElement(By.id(R.id.header_advanced)).click();
driver.findElement(By.id(R.id.header_advanced)).click();
// Assert no crash
assertTrue(driver.findElements(By.id(R.id.error_dialog)).isEmpty());
}
Running this script on every commit prevents the regression from resurfacing.
6.3 Cross‑Session Learning and Regression Script Generation
SUSA retains knowledge of explored screens across runs. If a particular preference consistently leads to a dead‑end (e.g., a preference that launches a broken subsystem), the platform marks it as a “cold spot” and prioritizes it in subsequent explorations. Over time, the accumulated data yields a set of auto‑generated Appium (Android) + Playwright (Web) scripts that cover the majority of reachable states, including those discovered only through persona‑driven behavior.
These scripts are not a replacement for hand‑crafted unit or instrumentation tests; rather, they act as a safety net that catches edge cases missed by traditional approaches. Teams can integrate the generated scripts into their nightly test suite, review them for relevance, and promote the most valuable ones into the permanent regression pack.
Checklist for Settings‑Page Release Readiness
Before merging a release candidate, run through this concise checklist. Each item can be ticked off manually or verified via the automated suites described earlier.
| ✅ Item | Verification Method |
|---|---|
| Settings activity launches from all expected entry points (nav drawer, action bar, deep link) | UI Automator test + manual smoke |
| Every toggle, checkbox, and radio button updates UI and SharedPreferences instantly | Espresso preference tests |
| All EditText preferences accept valid input and reject invalid input with inline errors | Parameterized EditText tests |
| Sub‑screens open correctly and Back returns without duplicate fragments | UI Automator back‑stack check |
| Configuration changes (rotation, font scale, dark mode) preserve preference state | Manual rotation + automated config‑change test |
| TalkBack reads each element with correct state and purpose | Accessibility Test Framework (ATF) or manual TalkBack swipe |
| Touch targets ≥48dp, contrast ratio ≥4.5:1 | Layout Inspector + automated accessibility rules |
Settings activity is not exported (android:exported="false" in manifest) | adb shell pm dump grep |
| No debug‑only preferences visible in release build | Compare UIAutomator dump of debug vs release APK |
| Clearing app data via system Settings restores all defaults | adb shell pm clear + preference verification |
| No crash or ANR when rapidly toggling switches 50 times in 5 s | UI Automator stress loop |
| Intent to launch system settings resolves correctly and handles cancellation | Espresso Intents test |
Logcat contains no StrictMode, NullPointerException, or ANR lines during any test | Automated logcat filter + manual scan |
| Generated SUSA scripts (if used) pass on CI | Run susatest-agent test app.apk --persona curious and verify exit code |
If any item fails, treat it as a blocker until resolved, and add a test that covers the failure mode to prevent regression.
Closing Takeaways
Testing an Android settings page is more than a checklist of UI interactions; it is a disciplined effort to verify persistence, system integration, accessibility, security, and resilience under real‑world usage patterns. By combining a well‑structured matrix, layered automation (UI Automator for cross‑app concerns, Espresso for fast intra‑app checks, and Intents testing for system interactions), and complementary exploratory techniques—such as persona‑driven autonomous testing with tools like SUSA—teams can uncover defects that stay hidden in traditional test suites.
A diligent manual pass, guided by the matrix, catches device‑specific quirks and OEM customizations that automated scripts might miss. Automated suites give rapid feedback on every commit, while autonomous exploration surfaces surprising edge cases—like a dead button exposed only by an impatient user’s rapid taps—providing automatically generated regression scripts that keep the code base honest over time.
Finally, embed the settings‑page checklist into your definition of done. When each item is green, you can ship with confidence that the screen will not silently break notifications, leak data, or frustrate users who rely on it to tailor the app to their needs. The result is a more stable product, fewer support tickets, and a better experience for every persona that opens Settings.
Test Your App Autonomously
Upload your APK or URL. SUSA explores like 11 real users — finds bugs, accessibility violations, and security issues. No scripts. New to the category? Start with what autonomous product intelligence & QA means.
Try SUSA Free