How to Test Onboarding Flow on iOS (Complete Guide)
How to Test Onboarding Flow on iOS (Complete Guide) begins with understanding why the onboarding experience is a critical gatekeeper for user retention and app success. A smooth onboarding sequence se
How to Test Onboarding Flow on iOS (Complete Guide) begins with understanding why the onboarding experience is a critical gatekeeper for user retention and app success. A smooth onboarding sequence sets expectations, reduces friction, and drives key metrics that directly influence App Store ratings and organic growth. Conversely, a broken onboarding flow can cause immediate drop‑off, negative reviews, and lost revenue. This guide walks you through a complete, practical approach to testing onboarding on iOS, from why it matters to building a test matrix, executing manual and automated checks, validating accessibility and privacy, catching production‑only edge cases, and leveraging autonomous, persona‑driven exploration to uncover bugs that scripted tests miss.
How to Test Onboarding Flow on iOS (Complete Guide): Why It Matters
The Business Impact of Onboarding Quality
Onboarding is often the first sustained interaction a user has with an app. Studies show that a 1‑second delay in perceived load time can increase abandonment by up to 7 %. When onboarding includes mandatory steps such as account creation, permission requests, or tutorial screens, any friction multiplies. A crash, an unresponsive button, or a confusing instruction can push a user to abandon the app before they ever experience its core value. In the App Store, low retention rates signal to the algorithm that the app is less engaging, which reduces discoverability. Therefore, rigorous onboarding testing is not a quality‑nice‑to‑have; it directly affects key performance indicators such as Day‑1 retention, conversion funnels, and lifetime value.
Common Failure Modes in Production
Production onboarding failures tend to fall into a few categories:
- UI‑state mismatches: Buttons that appear enabled but are actually disabled due to a race condition between network calls and UI updates.
- Permission handling gaps: The app assumes the user granted location access, but the system dialog was dismissed, leaving a nil location manager and causing a silent failure.
- Localization breaks: Hard‑coded strings that overflow on longer languages, causing clipped text or layout shifts.
- Accessibility oversights: Missing accessibility labels or improper trait assignments that prevent VoiceOver users from completing steps.
- Data‑privacy slips: Accidentally logging personally identifiable information (PII) to the console or sending it to analytics before user consent.
- Network‑dependency assumptions: Onboarding screens that require a live API call but fail to show an informative error when the device is offline.
Understanding these patterns helps you design a test matrix that targets the real risks rather than merely checking that a button exists.
How to Test Onboarding Flow on iOS (Complete Guide): Building a Comprehensive Test Matrix
A test matrix organizes scenarios by dimension (happy path, error paths, edge cases, accessibility, security/privacy) and by variation (device model, iOS version, language, network condition). Below is a practical matrix you can copy into a spreadsheet or test‑management tool.
| Dimension | Scenario ID | Description | Expected Result | Variations |
|---|---|---|---|---|
| Happy Path | ONB‑HP‑01 | User launches app, sees welcome screen, taps “Get Started” | Welcome screen transitions to sign‑up screen | iPhone 14 Pro, iPhone SE (2022), iOS 16‑18 |
| Happy Path | ONB‑HP‑02 | User enters valid email, password, taps “Create Account” | Account created, proceeds to permission request screen | Same as above |
| Error Path | ONB‑EP‑01 | User taps “Get Started” without filling any fields | Inline validation shows “Email required” under email field | All devices, landscape/portrait |
| Error Path | ONB‑EP‑02 | User enters malformed email (e.g., “test@”) | Inline validation shows “Invalid email format” | All devices |
| Edge Case | ONB‑EC‑01 | Network loss after tapping “Create Account” but before server response | App shows retry toast, does not crash, retains entered data | Airplane mode, Wi‑Fi off, cellular off |
| Edge Case | ONB‑EC‑02 | User rapidly taps “Get Started” 10 times in 2 seconds | Only one navigation event occurs, no duplicate screens | Stress test |
| Accessibility | ONB‑AX‑01 | VoiceOver user navigates welcome screen | Each element has a meaningful label, hints, and correct traits | VoiceOver on, iOS 16‑18 |
| Accessibility | ONB‑AX‑02 | Dynamic type set to largest size | All text scales, no clipping, layout remains usable | Largest accessibility text size |
| Security/Privacy | ONB‑SP‑01 | App attempts to send email to analytics before user consents to data sharing | No network call containing email address is made | Network monitor enabled |
| Security/Privacy | ONB‑SP‑02 | Location permission denied; app still tries to fetch location | App handles denial gracefully, shows alternative UI or explanatory message | Denied location permission |
How to Use the Matrix
- Prioritize by risk: Happy path and critical error paths (e.g., missing validation) get executed on every build.
- Rotate variations: For each release, run the matrix on at least two device sizes, two iOS versions, and one language other than English (e.g., Spanish or Japanese) to catch layout and localization bugs.
- Automate the repeatable steps: Happy path and validation scenarios are ideal for XCUITest; edge cases like network loss can be simulated with the Network Link Conditioner or custom URLProtocol stubs.
- Track flaky results: If a scenario fails intermittently, mark it for investigation—often a sign of a race condition or timing‑dependent UI update.
How to Test Onboarding Flow on iOS (Complete Guide): Manual Testing Step‑by‑Step
Manual testing remains valuable for exploratory checks, especially when evaluating subjective aspects like clarity of copy or perceived speed. Follow this step‑by‑step routine for each onboarding variant you wish to validate.
Preparation
- Device Setup: Use a physical device (not just a simulator) to capture real‑world touch latency and sensor behavior. Install the latest build via TestFlight or Xcode -> Devices and Simulators.
- Environment: Disable background app refresh, enable “Reduce Motion” off, and set the device to a known language/region. For privacy tests, reset advertising identifier (Settings → Privacy & Security → Apple Advertising → Reset Advertising Identifier).
- Tools: Have the Console app open (macOS) to capture logs, and a network inspector such as Charles Proxy or mitmproxy to view API calls.
Execution
- Launch Cold Start: Force‑quit the app, then tap its icon. Observe launch splash screen duration; note any blank white screens.
- Welcome Screen: Verify that all UI elements are present, correctly aligned, and that touch targets meet the 44 pt minimum. Tap each button to ensure navigation.
- Form Entry: For each input field:
- Tap to focus, verify keyboard type matches expected (email, password, number).
- Enter valid data, then invalid data, and confirm inline validation appears instantly.
- Test paste, cut, and auto‑fill functionalities.
- Progression: After completing a step, tap the primary call‑to‑action. Watch for activity indicators; ensure they disappear on success or error.
- Permission Dialogs: When the app requests camera, location, or notifications, note the timing. Dismiss the dialog via “Don’t Allow” and verify the app handles the denial without crashing.
- Network Conditions: Enable Airplane mode after a specific step (e.g., after pressing “Create Account”) and observe error handling. Then restore connectivity and confirm retry works.
- Accessibility Check: Turn on VoiceOver, navigate using swipe gestures, and listen to each element’s description. Ensure that actions are announced correctly and that hints guide the user.
- Dynamic Type: Go to Settings → Accessibility → Display & Text Size → Larger Text, select the largest size, and revisit each screen. Verify that no text is truncated and that scroll views adapt.
- Cleanup: After completing the flow, sign out or reset the app state (via Settings → General → iPhone Storage → Offload App) to test the onboarding again from a clean slate.
Observation Checklist
- Visual: No overlapping elements, correct contrast ratio (≥ 4.5:1 for normal text).
- Tactile: No ghost taps; each tap produces a single, expected response.
- Temporal: No unexplained delays > 2 seconds between user action and UI update.
- Auditory: VoiceOver reads all labels; error tones are distinct.
- Logical: State transitions are irreversible only when intended (e.g., you cannot go back to welcome after account creation unless explicitly allowed).
Manual testing should be performed at least once per release candidate and after any UI‑heavy change (e.g., new localization, design refresh).
How to Test Onboarding Flow on iOS (Complete Guide): Automated Approaches with XCTest and XCUITest
Automated tests give you regression safety and enable continuous integration. XCTest provides unit‑level validation; XCUITest drives the UI. Below we outline a layered strategy.
Unit Testing View‑Model Logic
If your onboarding follows MVVM or similar, test the view‑model in isolation:
import XCTest
@testable import MyApp
final class OnboardingViewModelTests: XCTestCase {
func testEmailValidation() {
let vm = OnboardingViewModel()
XCTAssertTrue(vm.isEmailValid("user@example.com"))
XCTAssertFalse(vm.isEmailValid("user@"))
XCTAssertFalse(vm.isEmailValid(""))
}
func testAccountCreationSuccess() {
let mockService = MockAuthService(result: .success(User(token: "abc")))
let vm = OnboardingViewModel(authService: mockService)
vm.email = "user@example.com"
vm.password = "Secure123"
vm.createAccount()
XCTAssertEqual(vm.state, .accountCreated)
}
func testAccountCreationNetworkFailure() {
let mockService = MockAuthService(result: .failure(.networkError))
let vm = OnboardingViewModel(authService: mockService)
vm.email = "user@example.com"
vm.password = "Secure123"
vm.createAccount()
XCTAssertEqual(vm.state, .error(.networkError))
}
}
These tests run in milliseconds and catch logic regressions early.
UI Testing Core Flows
XCUITest scripts interact with the actual app. Keep them readable by using descriptive element identifiers (accessibility identifiers, not labels).
import XCTest
final class OnboardingUITests: XCTestCase {
let app = XCUIApplication()
override func setUp() {
continueAfterFailure = false
app.launchArguments.append("-ui_testing")
app.launch()
}
func testHappyPathOnboarding() {
// Welcome
XCTAssertTrue(app.staticTexts["Welcome to MyApp"].exists)
app.buttons["Get Started"].tap()
// Sign‑up form
let emailField = app.textFields["EmailAddress"]
emailField.tap()
emailField.typeText("tester@example.com")
let passwordField = app.secureTextFields["Password"]
passwordField.tap()
passwordField.typeText("StrongPass!23")
app.buttons["Create Account"].tap()
// Permission request (example: notifications)
let allowButton = app.alerts["Allow Notifications?"].firstButton"].firstExists.allowfirst
XCTAssertTrue(allowButton.waitForExistence(timeout: 5))
allowButton.tap()
// Final screen
XCTAssertTrue(app.staticTexts["Your account is ready!"].exists)
}
}
Tips for Stable XCUITest:
- Assign a unique
accessibilityIdentifierto every interactive element you need to query. - Avoid relying on dynamic text; use identifiers or static text that is unlikely to change.
- Use
waitForExistence(timeout:)instead ofsleep. - Reset app state between tests by launching with a custom launch argument (
-ui_testing) that triggers a test‑mode reset inapplication(_:didFinishLaunchingWithOptions:).
Simulating Network Conditions
You can inject a custom URLProtocol to simulate latency or failures:
class MockURLProtocol: URLProtocol {
static var errorToReturn: Error?
static var delay: TimeInterval = 0
override class func canInit(with request: URLRequest) -> Bool {
return true
}
override class func canonicalRequest(for request: URLRequest) -> URLRequest {
return request
}
override func startLoading() {
if let delay = Self.delay, delay > 0 {
Thread.sleep(forTimeInterval: delay)
}
if let error = Self.errorToReturn {
client?.urlProtocol(self, didFailWithError: error)
} else {
// Return a stubbed success response
let response = HTTPURLResponse(url: request.url!, statusCode: 200, httpVersion: nil, headerFields: nil)!
client?.urlProtocol(self, didReceive: response, cacheStoragePolicy: .notAllowed)
client?.urlProtocol(self, didLoad: Data())
}
client?.urlProtocolDidFinishLoading(self)
(self)
)
}
override func stopLoading() { }
}
// In your test setup:
URLProtocol.registerClass(MockURLProtocol.self)
MockURLProtocol.errorToReturn = NSError(domain: NSURLErrorDomain, code: NSURLErrorNotConnectedToInternet, userInfo: nil)
Then run your XCUITest; the onboarding flow will encounter the simulated offline condition and you can assert that the app shows an appropriate retry UI.
Data‑Related to the matrix above, you can parameterize XCUITest to run the same script across multiple locales and device types using xcodebuild with destination specifiers:
xcodebuild test \
-workspace MyApp.xcworkspace \
-scheme MyAppUITests \
-destination "platform=iOS Simulator,name=iPhone 14,OS=17.2" \
-only-testing:OnboardingUITests/testHappyPathOnboarding \
-only-testing:OnboardingUITests/testEmailValidation_Locale_es \
-only-testing:OnboardingUITests/testEmailValidation_Locale_ja
You can embed locale switching in your test by calling UserDefaults.standard.set(["es"], forKey: "AppleLanguages") before app.launch().
How to Test Onboarding Flow on iOS (Complete Guide): Leveraging CI/CD for Onboarding Validation
Continuous integration ensures that onboarding regressions are caught before they reach TestFlight or the App Store. Integrate both unit and UI tests into your pipeline, and add a few extra validation steps.
Pipeline Stages
- Build – Compile the app for the simulator and a generic device target.
- Unit Test – Run
xcodebuild testtargeting only the unit test target. - Static Analysis – Execute
swiftlintandoclintto catch style and potential bugs. - Security Scan – Run a tool like
MobSForOWASP Dependency‑Checkon the built.ipato detect hard‑coded secrets or insecure networking flags. - UI Test Matrix – Execute the XCUITest suite on a matrix of simulators (e.g., iPhone SE, iPhone 14 Pro, iPad Air) and iOS versions (latest‑2, latest‑1, latest).
- Artifact Collection – Save test logs, screenshots on failure, and a video recording of the UI test run (using
xcrun simctl io booted recordVideo). - Notify – Post a summary to Slack or Teams, tagging the responsible engineer if any onboarding test fails.
Example GitHub Actions Workflow (simplified)
name: iOS Onboarding CI
on:
push:
branches: [ main ]
pull_request:
jobs:
build-test:
runs-on: macos-latest
strategy:
matrix:
destination: [
"platform=iOS Simulator,name=iPhone SE (3rd generation),OS=17.2",
"platform=iOS Simulator,name=iPhone 14 Pro,OS=17.2",
"platform=iOS Simulator,name=iPad Air (5th generation),OS=17.2"
]
steps:
- uses: actions/checkout@v3
- name: Set up Xcode
run: sudo xcode-select -switch /Applications/Xcode_15.2.app
- name: Install dependencies
run: brew install carthage swiftlint
- name: Build
run: |
xcodebuild -workspace MyApp.xcworkspace -scheme MyApp \
-destination "${{ matrix.destination }}" \
-quiet build
- name: Run Unit Tests
run: |
xcodebuild test -workspace MyApp.xcworkspace -scheme MyAppTests \
-destination "${{ matrix.destination }}" \
-only-testing:MyAppTests
- name: Run Onboarding UI Tests
run: |
xcodebuild test -workspace MyApp.xcworkspace -scheme MyAppUITests \
-destination "${{ matrix.destination }}" \
-only-testing:OnboardingUITests/testHappyPathOnboarding \
-only-testing:OnboardingUITests/testEmailValidation_Locale_es \
-only-testing:OnboardingUITests/testEmailValidation_Locale_ja
- name: Upload Test Artifacts
if: failure()
uses: actions/upload-artifact@v3
with:
name: test-logs-${{ matrix.destination }}
path: |
**/TestResult.xcresult
**/ScreenShot*.png
This workflow guarantees that every commit is exercised on multiple device profiles, catching device‑specific layout or runtime issues early.
Additional CI Checks
- App Launch Time: Use
xcrun xctrace record --template "App Launch"to measure cold‑start time; fail if > 2 seconds. - Binary Size: Verify that the onboarding bundle does not exceed a defined threshold (e.g., 5 MB) to avoid excessive download time.
- Privacy Manifest Validation: Ensure the app’s
PrivacyInfo.xcfileaccurately declares any data collected during onboarding (e.g., email, device ID).
How to Test Onboarding Flow on iOS (Complete Guide): Accessibility and Privacy Considerations
Accessibility and privacy are not optional add‑ons; they are legal requirements in many jurisdictions and directly affect user trust. Embedding checks for both into your onboarding test matrix prevents costly remediation later.
Accessibility Testing Checklist
| Item | How to Verify | Tool |
|---|---|---|
All UI elements have an accessibilityIdentifier | Inspect the view hierarchy via Xcode’s Debug View Hierarchy or print app.debugDescription in XCUITest | Xcode |
| Labels are concise, localized, and avoid redundancy | Run localized builds and listen with VoiceOver | VoiceOver + manual |
| Touch targets meet 44 pt minimum | Use the Accessibility Inspector’s “Show Touch Targets” overlay | Accessibility Inspector |
| Dynamic type scales correctly | Set largest text size, verify no clipping | Settings + manual |
| Screen layout does not break when VoiceOver is on | Navigate with swipe gestures, ensure focus moves logically | VoiceOver |
| Accessibility traits are correct (e.g., button, link, header) | Inspect traits in the Accessibility Inspector | Accessibility Inspector |
| No inaccessible custom gestures | Ensure any custom gesture has an accessible alternative | Manual testing |
| Error announcements are distinct | Trigger validation errors, listen for VoiceOver announcements | VoiceOver |
Automate as much as possible: you can write a UI test that iterates over all elements returned by app.descendants(matching: .any) and asserts that element.label.isEmpty == false for non‑decorative items.
Privacy Testing Checklist
| Check | Method | Tool |
|---|---|---|
| No PII logged to console | Run app with Console.app, filter for @"email", @"password", @"token" | Console |
| Analytics endpoints respect user consent | Intercept network calls with Charles Proxy; verify that calls to analytics endpoints contain no user‑identified payload before consent | Charles/mitmproxy |
| App does not request unnecessary permissions | Review Info.plist for usage description keys; ensure each is justified at runtime | Manual review |
| Permission rationale strings are present and localized | Build for each language, inspect the alert title/message | Xcode |
| Data stored in Keychain or UserDefaults is encrypted | Verify that sensitive data is saved via Keychain with appropriate accessibility | Manual code review |
| App’s privacy manifest accurately reflects data usage | Run xcrun privacy-utilities lint --manifest PrivacyInfo.xcfile | Xcode privacy utilities |
| No background location usage when denied | Simulate denial, then background the app and check location services status | Xcode Debug → Location |
#### Example: Unit Test for Analytics Consent
import XCTest
@testable import MyApp
final class AnalyticsPrivacyTests: XCTestCase {
func testAnalyticsDoesNotSendEmailBeforeConsent() {
let mockAnalytics = MockAnalytics()
let onboarding = OnboardingFlow(analytics: mockAnalytics)
onboarding.email = "user@example.com"
// Simulate user has NOT given consent
onboarding.consentGiven = false
onboarding.completeOnboarding()
XCTAssertTrue(mockAnalytics.sentEvents.isEmpty) // no event fired
}
func testAnalyticsSendsEventAfterConsent() {
let mockAnalytics = MockAnalytics()
let onboarding = OnboardingFlow(analytics: mockAnalytics)
onboarding.email = "user@example.com"
onboarding.consentGiven = true
onboarding.completeOnboarding()
XCTAssertTrue(mockAnalytics.sentEvents.contains { $0.name == "onboarding_completed" })
}
}
In this test, MockAnalytics records any events that would be sent to a remote endpoint; the assertions guarantee that no personally identifiable data leaks before the user opts in.
Combining Accessibility and Privacy in a Single UI Test
You can write a test that first enables VoiceOver, runs the onboarding flow, and then asserts that no analytics call containing email was made:
func testOnboardingAccessibleAndPrivate() throws {
app.launchArguments.append("-ui_testing")
app.launch()
// Enable VoiceOver via accessibility API (private but usable in UI tests)
XCUIDevice.shared.press(.home)
let springboard = XCUIApplication(bundleIdentifier: "com.apple.springboard")
springboard.tap() // opens accessibility shortcut
// Assume triple‑click home toggles VoiceOver; adjust as needed
// ... (implementation omitted for brevity)
// Run happy path
testHappyPathOnboarding() // reuse previous test
// Verify VoiceOver can navigate all steps
XCTAssertTrue(app.staticTexts["Your account is ready!"].exists)
// Check network log for PII
// Assuming we have a test hook that exposes captured requests
let capturedRequests = app.otherRequests["testHook"]
XCTAssertFalse(capturedRequests.contains { $0.body?.contains("email") == true })
}
While enabling VoiceOver programmatically in UI tests is fragile, it demonstrates the principle: accessibility and privacy validation can be scripted together.
How to Test Onboarding Flow on iOS (Complete Guide): Edge Cases that Only Appear in Production
Some defects remain hidden in the simulator or limited device farm but surface when real users interact with the app under varying conditions. Below are concrete production‑only edge cases and how to surface them in testing.
1. Intermittent Network Re‑authentication Tokens
Problem: The onboarding flow exchanges a temporary token for a permanent one. If the network drops after the temporary token is sent but before the permanent token arrives, the app may retain the temporary token and attempt to reuse it, resulting in a 401 error that is not handled gracefully.
Simulation: Use a network throttling tool (e.g., networksetup on macOS to add packet loss, or Charles Proxy’s “Throttle” settings) to introduce 30 % packet loss right after the /requestTempToken endpoint. Then assert that the app shows a retry option and does not crash.
2. Locale‑Specific Date/Time Formatting
Problem: An onboarding screen shows a “Valid until” date formatted with DateFormatter using the default locale. In regions where the day‑month order differs (e.g., dd/MM/yyyy vs. MM/dd/yyyy), the string may be misinterpreted, causing confusion or validation failures.
Detection: Run the app with a locale like ar_SA (Arabic Saudi Arabia) and verify that the displayed date matches the expected format. Use XCTest to assert that the label’s text matches a regex pattern for the locale.
3. Background App Refresh Interrupting Onboarding
Problem: If the system decides to launch a background fetch while the user is mid‑onboarding, the app might process a silent push notification that attempts to navigate to the home screen, causing the onboarding stack to be popped unexpectedly.
Simulation: In Xcode, simulate a background fetch (Debug → Simulate Background Fetch) after the user has entered email but before tapping “Create Account”. Verify that the UI remains on the same screen and that any pending network calls are not cancelled.
4. Dark Mode Appearance Issues
Problem: Custom colors defined with hard‑coded RGB values may not adapt to Dark Mode, resulting in low contrast or invisible text.
Detection: Use the Accessibility Inspector’s “Show Colors” toggle to switch between light and dark appearances while the app is running on a device. Automate by setting UITraitCollection(userInterfaceStyle: .dark) in a UI test and asserting contrast ratios via a helper that reads the UIColor of each label.
5. Biometric Authentication Prompt Timing
Problem: Some apps offer Face ID/Touch ID as an optional shortcut after onboarding. If the biometric prompt appears while the keyboard is still visible, the two overlays can clash, making the prompt unusable.
Test: After completing onboarding, trigger the biometric login flow (via LAContext in a test hook) while the keyboard is still present (simulate by not dismissing the keyboard). Ensure the system alert is displayed above the keyboard and that the user can still interact with it.
6. Push Notification Permission Prompt Race
Problem: The app requests push notification permissions immediately after account creation. If the user denies, the app may still try to register for remote notifications in the background, leading to silent failures that later affect features dependent on push.
Test: Deny the permission when the alert appears, then background the app and simulate a remote notification (xcrun simctl push ). Verify that the app does not crash and that it logs an appropriate “not authorized” message.
7. Low‑Storage Condition
Problem: When the device storage is nearly failed, saving user preferences to UserDefaults or writing to the Keychain may return nil, causing the onboarding flow to think the user skipped a step.
Simulation: Fill the device storage with large files (via dd if=/dev/zero of=bigfile bs=1m count=4000 on a connected Mac, then copy to the device via iTunes File Sharing) to leave < 50 MB free. Run onboarding and verify that the app handles the failure gracefully (e.g., shows a “Unable to save settings” alert and allows retry).
8. Multitasking Interruptions (Slide‑Over / Split View on iPad)
Problem: On iPad, a user may swipe in a Slide‑Over app while onboarding is in progress, causing the onboarding app to move to the background. If the app does not correctly preserve its UI state, returning to it may show a stale screen.
Test: Launch the app on an iPad simulator, start onboarding, then invoke Slide‑Over (⌘ + Shift + →) to open another app. After a few seconds, swipe back and confirm the onboarding screen is exactly where the user left it, with any entered text preserved.
By deliberately injecting these conditions—either through device settings, network tools, or system simulators—you can convert “production‑only” mysteries into repeatable test cases.
How to Test Onboarding Flow on iOS (Complete Guide): Using Autonomous, Persona‑Driven Exploration (SUSA)
While scripted tests validate known paths, autonomous exploration can surface unexpected behavior by simulating how real people interact with the app. SUSA (SUSATest) is an autonomous QA platform that explores an iOS app without pre‑written scripts, using a set of defined user personas.
How SUSA Works
- Ingestion: You provide either an IPA file or a link to a TestFlight build. SUSA installs the app on a fleet of real devices (or emulators) representing various models and iOS versions.
- Persona Engine: Each persona has a behavior profile:
- *Curious*: Taps every visible element, explores deep hierarchies.
- *Impatient*: Performs quick taps, often skips reading long text.
- *Novice*: Prefers clearly labeled buttons, avoids ambiguous icons.
- *Adversarial*: Attempts malformed inputs, rapid double‑taps, and unexpected gestures.
- *Elderly*: Uses larger touch targets, slower gestures, relies on accessibility features.
- *Accessibility*: Relies on VoiceOver, Switch Control, or increased contrast.
- *Power User*: Utilizes shortcuts, prefers keyboard‑like interactions, tries hidden gestures.
- Exploration: The platform drives the app through sequences of taps, scrolls, text entry, and system interactions (alerts, permission dialogs, orientation changes) while monitoring for crashes, ANRs, dead ends, accessibility violations, and security/privacy leaks.
- Learning: Over successive runs, SUSA builds a map of visited screens and dead ends, prioritizing unexplored areas and refining persona behavior based on observed outcomes.
- Output: After a session, you receive a detailed report with:
- Crash logs and stack traces.
- Video recordings of each session.
- Lists of UI elements that lack accessibility labels or have insufficient contrast.
- Potential privacy leaks (e.g., data sent to analytics before consent).
- Regressions detected compared to the baseline run.
- Auto‑generated Appium (Android) and Playwright (Web) scripts for the flows it discovered (useful if you later want to codify specific paths).
Applying SUSA to Onboarding Testing
When you point SUSA at an onboarding‑heavy build, you can expect it to:
- Discover hidden entry points: For example, a “Skip” button that is only visible after a certain swipe gesture, which a scripted test might never press because it’s not in the predefined flow.
- Uncover persona‑specific friction: The *Impatient* persona
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