How to Write Test Cases for Biometric Login (With Examples)

How to Write Test Cases for Biometric Login (With Examples)

June 16, 2026 · 18 min read · How-To Guides

How to Write Test Cases for Biometric Login (With Examples)

Biometric login has become a default gatekeeper for mobile apps and web portals, yet many teams still treat it as a black‑box feature and write only a handful of superficial checks. This guide shows how to construct a high‑signal test suite that covers enrollment, authentication, error handling, spoof resistance, and fallback paths, while also linking each case to requirements and prioritizing effort. You will find a concrete test matrix with 20+ examples, a prioritization table, practical automation snippets, and a short checklist you can copy into your test plan. The approach works whether you write tests manually, with Appium/Playwright, or alongside an autonomous explorer such as SUSA.

How to Write Test Cases for Biometric Login (With Examples) – Test Case Anatomy

A test case is more than a list of steps; it is a contract between the specification and the implementation. Every case should contain the following fields:

FieldPurposeTips
IDUnique identifier (e.g., BL‑001)Use a prefix that indicates the feature area (BL = Biometric Login).
TitleShort, readable summaryStart with a verb and the biometric modality (e.g., “Verify successful fingerprint enrollment”).
PreconditionsState that must be true before executionInclude device OS version, biometric sensor availability, account state, and any required mocks.
StepsOrdered actions the tester or automation performsKeep each step atomic; avoid bundling multiple actions unless they are inseparable.
Expected ResultObservable outcome that determines pass/failExpress in terms of UI changes, API responses, or system logs.
Postconditions (optional)State left after the test (useful for chaining)Note if the biometric template remains enrolled or if the app returns to a login screen.
PriorityRelative importance for execution orderMap to risk (e.g., P0 = crash‑blocking, P1 = functional, P2 = usability).
TraceabilityLink to requirement IDs or user storiesEnables impact analysis when requirements change.

When you fill out each field consistently, reviewers can quickly judge coverage, and automation engineers can translate the steps into code without ambiguity.

Writing Clear Preconditions

Preconditions often cause flaky tests when they are omitted or vague. For biometric login, enumerate:

Documenting these items prevents a test from passing on one device and failing on another simply because the sensor was disabled.

Structuring Steps for Automation

Each step should map to a single API call or UI interaction. For example:

  1. Launch the app and navigate to the Settings → Security → Biometric Login screen.
  2. Tap “Enroll Fingerprint”.
  3. Place a registered finger on the sensor (simulated via adb emu finger touch ).
  4. Wait for the enrollment success dialog.

If you are automating on the web with Playwright, the equivalent steps might involve calling page.evaluate(() => navigator.credentials.get({…})) and mocking the PublicKeyCredential response.

How to Write Test Cases for Biometric Login (With Examples) – Positive and Negative Cases

Positive tests verify that the happy path works under normal conditions. Negative tests confirm that the system correctly rejects invalid or malicious input. Edge cases sit between these categories, often revealing timing or resource‑exhaustion bugs.

Positive Test Matrix (20+ Examples)

Below is a comprehensive table you can adapt to your test management tool. Each row includes an ID, preconditions, steps, and expected result. Feel free to add columns for priority or requirement traceability.

IDPreconditionsStepsExpected Result
BL‑001Device has fingerprint sensor; no biometric enrolled for app; user at login screen.1. Enter valid username/password. 2. Tap “Use Fingerprint”. 3. Place enrolled finger on sensor.Login succeeds; biometric token stored; user taken to home screen.
BL‑002Device has face auth; user logged out; face not enrolled.1. Navigate to Enroll Face. 2. Follow on‑screen prompts to move head in a circle. 3. Confirm enrollment.Enrollment success dialog appears; face template saved in secure enclave.
BL‑003Fingerprint already enrolled; user at login screen.1. Tap “Login with Fingerprint”. 2. Present the same finger.Immediate login without credential entry.
BL‑004Face enrolled; user at login screen; ambient low light.1. Tap “Login with Face”. 2. Look at camera.Login succeeds (system compensates for low light).
BL‑005No biometric enrolled; user chooses PIN fallback.1. Tap “Use PIN”. 2. Enter correct 6‑digit PIN.Login succeeds; no biometric prompt shown.
BL‑006Biometric enrollment in progress; user cancels mid‑flow.1. Start fingerprint enrollment. 2. After first swipe, tap “Cancel”.Enrollment aborts; no partial template saved; user returns to previous screen.
BL‑007Device locked with PIN; biometric sensor disabled via admin policy.1. Attempt to open biometric login screen. 2. Observe UI.Biometric option hidden or disabled; fallback to PIN/password shown.
BL‑008Multiple fingerprints enrolled (index and thumb).1. Attempt login with index finger. 2. Repeat with thumb.Both attempts succeed; system accepts any enrolled finger.
BL‑009Face enrolled; user wears glasses; then removes them.1. Login with glasses on. 2. Remove glasses, login again.Both attempts succeed (system tolerant to minor appearance changes).
BL‑010Iris sensor present; user enrolls iris.1. Navigate to Iris Enrollment. 2. Align eye with guide. 3. Confirm.Enrollment success; iris template stored.
BL‑011Iris enrolled; user attempts login with eyes closed.1. Look at sensor with eyelids shut.Login fails; system prompts “Eye not detected”.
BL‑012Biometric sensor reports temporary error (e.g., overheating).1. Trigger sensor error via adb shell cmd uimodule set‑error fingerprint. 2. Attempt login.App shows error dialog and offers fallback to password/PIN.
BL‑013User attempts login after 5 consecutive failed attempts.1. Provide wrong fingerprint five times. 2. Try a sixth attempt with correct finger.Sixth attempt blocked; system imposes timeout or requires password.
BL‑014App updated; existing biometric credential must be re‑validated.1. Install app update. 2. Attempt biometric login.System asks for device PIN/password to re‑authenticate biometric before granting access.
BL‑015Device switched from fingerprint to face auth via settings.1. Disable fingerprint in system settings. 2. Enable face auth. 3. Attempt login.Login uses face sensor; fingerprint option no longer appears.
BL‑016User enrolls biometric while device is locked with a complex password.1. Lock device with password. 2. Unlock, go to enrollment. 3. Complete enrollment.Enrollment succeeds despite device lock complexity.
BL‑017Biometric login invoked from a deep link (e.g., myapp://login/biometric).1. Open URL via adb shell am start -d "myapp://login/biometric". 2. Present valid biometric.App launches, performs biometric check, and navigates to target screen.
BL‑018App running in background; biometric prompt appears via notification.1. Send a push that triggers biometric auth. 2. Present correct finger.App comes to foreground, authenticates, and executes the action tied to the notification.
BL‑019User attempts login with a dirty/foggy sensor.1. Smudge sensor surface. 2. Attempt login with clean finger.Login fails after configured retries; system suggests cleaning sensor.
BL‑020Device low battery (<10%); biometric login attempted.1. Set battery level via adb shell dumpsys battery set level 5. 2. Attempt login.Login proceeds; system may show low‑battery warning but does not block auth.
BL‑021User has accessibility service enabled (e.g., TalkBack).1. Enable TalkBack. 2. Navigate to biometric login screen. 3. Attempt login.All announcements are spoken; login succeeds with same timing as non‑accessibility mode.
BL‑022Biometric login invoked during device call (in‑call UI).1. Place a call. 2. While in call, trigger biometric login via app shortcut.Login screen appears over call UI; authentication works; call remains active.
BL‑023System biometric dialog customized with app logo and text.1. Set custom subtitle via BiometricPrompt.PromptInfo. 2. Invoke login.Dialog shows custom text; authentication behavior unchanged.
BL‑024User attempts login after device reboot with no credential cached.1. Reboot device. 2. Open app and try biometric login.System requests device PIN/password to unlock keystore before allowing biometric check.
BL‑025Biometric enrollment limited to max templates cleared by admin policy.1. Apply policy that wipes biometric data. 2. Try login.Login fails; app falls back to password/PIN and prompts re‑enrollment.

Negative Test Matrix (Representative Samples)

IDPreconditionsStepsExpected Result
BLN‑001No biometric enrolled; sensor present.1. Tap “Login with Fingerprint”. 2. Present any finger.Login fails; app shows “Fingerprint not recognized” and offers password fallback.
BLN‑002Face enrolled; user presents a photograph.1. Hold printed photo up to camera. 2. Attempt login.Login fails; liveness detection rejects static image.
BLN‑003Fingerprint enrolled; user presents a silicone spoof.1. Place spoof on sensor. 2. Attempt login.Login fails; sensor reports low confidence or spoof detected.
BLN‑004Device policy disallows biometric for apps with low security level.1. Set app security level to “low” in admin console. 2. Attempt biometric login.Biometric option hidden; only password/PIN available.
BLN‑005Biometric sensor disabled via settings put secure lock_biometric_weaker_unlock false.1. Attempt to open biometric login.App shows error “Biometric authentication unavailable”.
BLN‑006Rapid successive authentication attempts (flood).1. Send 20 auth requests in 2 seconds via automation script.After threshold, system imposes delay or locks biometric for a period.
BLN‑007User attempts login with incorrect PIN after biometric fallback.1. Fail biometric three times. 2. Enter wrong PIN.Login fails; account may be locked after configured attempts.
BLN‑008Biometric enrollment interrupted by incoming call.1. Start enrollment. 2. Receive call mid‑process.Enrollment pauses; after call ends, user must restart enrollment.
BLN‑009Device in developer mode with mock location; biometric auth tries to use location‑gated policy.1. Enable mock location. 2. Attempt login that requires location check.Login fails due to policy mismatch; system logs denial.
BLN‑010App attempts to use biometric before user has set up any lock screen credential.1. Ensure device has no PIN/Pattern/Password. 2. Try to invoke biometric login.System prompts user to set up lock screen credential before allowing biometric use.

These tables give you a starter set; you can expand them by combining modalities (e.g., face + fingerprint) or adding context‑specific steps such as “while device is in Do Not Disturb mode”.

Data Setup and Test Environment

Reliable biometric testing depends on a controllable environment. Emulators can simulate sensor input, but real hardware catches timing‑related bugs that emulators miss. Use a layered approach:

  1. Device farm – provision a matrix of devices covering each biometric modality you support (fingerprint, face, iris). Include at least one device with known sensor quirks (e.g., older fingerprint scanner with higher false‑reject rate).
  2. OS version baseline – test on the minimum supported Android/iOS version and the two most recent major releases.
  3. Biometric HAL stubs – on Android, you can replace the BiometricManager implementation with a mock that returns predefined results (SUCCESS, FAILED_LOCKOUT, ERROR_HW_UNAVAILABLE). This lets you inject error conditions without physically damaging the sensor.
  4. Server‑side mock – if your backend validates a biometric token, stub the endpoint to accept or reject tokens based on test case IDs.
  5. Test data isolation – create a dedicated test user account that is cleared before each test run. Use a unique username or a UUID suffix to avoid collisions with other test suites.

Example: Simulating a Fingerprint on Android Emulator


# Enroll a fake fingerprint (id 1)
adb emu finger touch 1
# Simulate a failed scan
adb emu finger touch 2
# Check biometric state
adb shell cmd uimodule list

Example: Mocking WebAuthn in Playwright


const { test, expect } = require('@playwright/test');

test.describe('Biometric login via WebAuthn', () => {
  test.use({
    // Override the navigator.credentials.get implementation
    bypassCSP: true,
  });

  test('successful fingerprint authentication', async ({ page }) => {
    await page.goto('https://example.com/login');
    await page.click('#biometric-login');

    // Mock the credential response
    await page.addInitScript(() => {
      navigator.credentials.get = async () => ({
        id: 'fake-credential-id',
        rawId: base64url.encode(Uint8Array.from([1,2,3])),
        type: 'public-key',
        response: {
          authenticatorData: new ArrayBuffer(0),
          clientDataJSON: new TextEncoder().encode('{}'),
          signature: new ArrayBuffer(0),
        },
      });
    });

    await page.fill('#username', 'testuser');
    await page.click('#submit');
    await expect(page.locator('#welcome')).toHaveText(/Welcome, testuser/);
  });
});

These snippets illustrate how you can drive both positive and negative scenarios without needing a physical biometric sensor for every test run.

Prioritization and Traceability

Not all test cases carry the same weight. Use a risk‑based matrix to decide what to automate first, what to keep manual, and what to deprioritize.

Prioritization Table

PriorityCriteriaExample Cases
P0Failure leads to security breach, crash, or blocked core login flow.BL‑003 (valid fingerprint login), BLN‑002 (photo spoof rejected), BLN‑006 (flood rate limiting).
P1Functional defect that degrades usability but does not block access.BL‑005 (PIN fallback), BL‑012 (sensor error handling), BL‑018 (background notification auth).
P2UX polish, edge‑case handling, or rare device configurations.BL‑009 (glasses tolerance), BL‑015 (switching auth modality), BL‑021 (TalkBack compatibility).
P3Nice‑to‑have, low impact, or covered by exploratory testing.BL‑024 (reboot keystore unlock), BL‑025 (admin policy wipe).

Map each test case ID to a requirement ID from your specification (e.g., REQ‑BL‑01: “User shall be able to log in using enrolled fingerprint”). Maintain a simple traceability matrix:

Requirement IDTest Case IDsStatus
REQ‑BL‑01BL‑001, BL‑003, BL‑007Covered
REQ‑BL‑02BLN‑001, BLN‑002, BLN‑003Covered
REQ‑BL‑03BL‑005, BL‑006, BL‑012Covered
REQ‑BL‑04BL‑009, BL‑010, BL‑011Covered
REQ‑BL‑05BLN‑006, BLN‑007, BLN‑008Covered

When a requirement changes, you can instantly see which tests need review.

Combining Manual Cases with Autonomous Exploration

Manual test cases give you deterministic coverage of known scenarios. Autonomous explorers, on the other hand, surface unexpected interactions by exercising the app with varied personas and random seeds. When you pair the two, you achieve both depth and breadth.

How an Autonomous Agent Works

An agent like SUSA uploads your APK (or points at a web URL), then:

  1. Model building – it constructs a state graph of screens, inputs, and dialogs as it taps, scrolls, and types.
  2. Persona injection – each run selects a persona (e.g., “impatient” taps quickly, “elderly” uses larger touch targets, “adversarial” tries malformed inputs).
  3. Biometric handling – the agent can invoke the platform’s biometric prompt and respond with success, failure, or error based on configured probabilities.
  4. Learning – visited screens and dead ends are stored; subsequent runs avoid re‑exploring known fruitless paths and focus on new edges.

Practical Integration

This approach catches production‑only issues such as:

By continuously feeding autonomous findings back into your test case repository, you keep the suite aligned with real‑world usage patterns.

Automation Strategies for Biometric Login

Automating biometric features requires stubbing or simulating the hardware layer because most CI environments lack genuine sensors. Below are patterns for Android (Appium/Espresso) and Web (Playwright) that you can adapt.

Android – Using Espresso with a Mock BiometricManager

  1. Add a test-only dependency that provides a fake BiometricManager.
  2. In your test Application subclass, replace the system service with the mock when Build.TYPE == "test".
  3. In the test, program the mock to return specific results.

// FakeBiometricManager.kt
class FakeBiometricManager @Inject constructor(
    private var result: Int = BiometricManager.BIOMETRIC_SUCCESS
) : BiometricManager() {
    override fun canAuthenticate(): Int = result
    override fun authenticate(
        executor: Executor,
        callback: BiometricPrompt.AuthenticationCallback
    ) {
        // Simulate async callback
        executor.execute {
            if (result == BiometricManager.BIOMETRIC_SUCCESS) {
                callback.onAuthenticationSucceeded(
                    BiometricPrompt.AuthenticationResult(CryptoObject(null))
                )
            } else {
                callback.onAuthenticationError(
                    BiometricPrompt.ERROR_NEGATIVE_BUTTON,
                    "Biometric error"
                )
            }
        }
    }
    fun setResult(r: Int) { result = r }
}

In your test:


@Before
fun setup() {
    val fake = FakeBiometricManager()
    fake.setResult(BiometricManager.BIOMETRIC_SUCCESS)
    // Replace the system service (pseudo‑code, actual implementation depends on DI framework)
    ServiceLocator.setBiometricManager(fake)
}

@Test
fun `valid fingerprint logs in`() {
    onView(withId(R.id.btn_fingerprint)).perform(click())
    // Mock returns success, so the app proceeds
    onView(withText(R.string.welcome)).check(matches(isDisplayed()))
}

To test failure, simply call fake.setResult(BiometricManager.BIOMETRIC_ERROR_HW_UNAVAILABLE) before the test.

Web – Playwright with WebAuthn Mock

The Web Authentication API (navigator.credentials.get) can be overridden as shown earlier. For more elaborate scenarios, you can simulate user presence, UV (user verification), and attestation statements using libraries like @github/webauthn-json.


const webauthn = require('@github/webauthn-json');

test('rejects missing user verification', async ({ page }) => {
  await page.goto('https://example.com/login');
  await page.click('#biometric-login');

  await page.addInitScript(() => {
    navigator.credentials.get = async () => {
      throw new Error('NotAllowedError'); // Simulates UV refusal
    };
  });

  await page.fill('#username', 'testuser');
  await page.click('#submit');
  await expect(page.locator('.error')).toHaveText(/Verification required/);
});

Cross‑Platform Tips

These patterns let you run hundreds of biometric login tests per commit without needing a lab of physical devices.

Checklist for Biometric Login Test Suite

Before you sign off a release, run through this concise checklist. Each item maps directly to the test matrices above.

If any item is unchecked, open a ticket and assign a priority based on the risk matrix earlier.

Real‑World Production Gotchas

Even the most thorough lab suite can miss issues that only appear under unpredictable field conditions. Below are several patterns that have surfaced in production for biometric login, along with suggested mitigations.

GotchaDescriptionMitigation
Intermittent sensor driftOver weeks, a fingerprint sensor’s false‑reject rate rises due to wear or skin changes.Implement periodic re‑enrollment prompts; monitor auth success ratios server‑side and trigger user‑notification when threshold crossed.
Privacy‑screen interferenceSome screen protectors or privacy films block IR or ultrasonic frequencies, causing face or iris auth to fail.Detect repeated failures and suggest checking screen accessory; fall back to knowledge‑based auth after two consecutive failures.
Biometric dialog hijackingA malicious overlay can capture the biometric prompt and harvest credentials.Use setConfirmationRequired(true) on Android BiometricPrompt to require user interaction; on web, rely on WebAuthn’s user presence flag.
Locale‑specific UI textIn certain languages, the default biometric prompt strings overflow, causing clipping or missing buttons.Test with pseudo‑localization and right‑to‑left layouts; provide custom prompt strings with sufficient length buffers.
Concurrent enrollment and authA user starts enrollment while another thread attempts auth, leading to corrupt keystore state.Serialize biometric operations via a mutex; reject new auth requests if enrollment is in progress.
Device admin policy changes mid‑sessionAn MDM push disables biometrics while the app is in the foreground, leaving the UI in an inconsistent state.Listen for ACTION_DEVICE_ADMIN_DISABLED and immediately hide biometric options, showing fallback.
Low‑memory killerOn low‑end devices, the system may kill the auth service mid‑callback, resulting in silent failure.Bind to the foreground service with START_FLAG_PRIORITY and handle onRebind gracefully; retry after a short delay.
Cross‑profile work‑personal separationOn Android Enterprise, work profile may have biometrics disabled while personal profile enables them.Query DevicePolicyManager.isBiometricAuthEnabled(userHandle) for the appropriate profile before showing the biometric option.
Network‑latency dependent fallbackSome apps defer to server‑side validation of the biometric token; high latency causes timeout and misleading UI.Keep token validation local where possible; if remote validation is required, display a spinner and enforce a short timeout with clear error.
Accessibility service focus theftServices like Switch Control can steal focus from the biometric dialog, preventing user interaction.Test with common accessibility services enabled; ensure the dialog retains focus or provides a way to regain it.
OEM‑specific biometric UIManufacturers like Samsung or Xiaomi replace the stock dialog with a full‑screen animation that may not respect your theme.Avoid hard‑coding dialog dimensions; rely on the system-provided BiometricPrompt API and verify behavior on flagship OEM devices.

Incorporate these observations into your exploratory testing charter. When you notice a pattern recurring in field logs, add a dedicated test case (e.g., “Biometric login succeeds after privacy screen removal”) and prioritize it based on observed impact.

Closing Takeaways

Writing effective test cases for biometric login is not a matter of checking a box that says “fingerprint works”. It requires a systematic approach that:

  1. Decomposes the feature into enrollment, authentication, error handling, spoof resistance, fallback, and cross‑cutting concerns such as accessibility and device policy.
  2. Captures each dimension in a structured test case with clear preconditions, atomic steps, and observable pass/fail criteria.
  3. Prioritizes based on risk, linking every case to a requirement so that impact analysis is trivial when specs evolve.
  4. Combines deterministic manual cases with stochastic autonomous exploration to achieve both depth (known paths) and breadth (surprising interactions).
  5. Automates wisely by mocking the biometric hardware layer where possible, while still validating real‑device behavior on a representative hardware at least once per release cycle.
  6. Learns from production by feeding field‑observed gotchas back into the test matrix, ensuring the suite evolves alongside the device ecosystem.

When you follow the process outlined here—starting with the exact phrase “How to Write Test Cases for Biometric Login (With Examples)” in your opening sentence, populating a rich test matrix, applying a risk‑based priority list, and augmenting manual effort with autonomous agents—you will deliver a biometric login feature that is not only functional but also resilient to the myriad ways users and attackers interact with modern authentication systems. Use the tables, snippets, and checklist as a living reference, and revisit them whenever you add a new modality, support a new OS version, or encounter a fresh failure mode in

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