Skip to content
QA Knowledge Hub

Test cases for OTP verification

Updated 2026-11-13 · 6 min read

Thirty cases for a delivered login code, including exact expiry boundaries and concurrent verification. Explicit fixture rules make resend and lockout results checkable.

How to answer in an interview

Ask whether this is login, contact verification or approval of a transaction. Clarify code length, expiry, retry limits and what resend does to an older code. Lead with a valid verification, then show how you would test expiry on the server and prevent a code from verifying the wrong account.

Scope and test data

Assume a delivered login code, not an authenticator-app TOTP. The example contract is six ASCII digits, a 180-second lifetime from server issuance, five wrong attempts per challenge and a 30-second resend cooldown. A successful resend invalidates the previous code; five wrong attempts lock that challenge. These are example product decisions, not OTP standards. Use a fake account such as [email protected] and a delivery stub; a fixture code such as 012345 must exist only in that stub. Do not send test messages to arbitrary phone numbers. OWASP recommends short-lived, single-use OTPs and controls against guessing; it does not prescribe this example policy.

The 30 cases below are a test design, not an execution report. Replace the example rules with approved requirements before recording pass or fail. Performance budgets and supported device versions must be agreed before execution.

Verification and input

IDCategoryTest caseExpected result
O01FunctionalEnter the current six-digit code before expiryLogin completes for the account bound to the challenge
O02FunctionalEnter a fixture code beginning with zeroAll six characters are preserved and verification succeeds
O03FunctionalPaste the complete code into the first inputAll digits populate in order and one verification can be submitted
O04NegativeSubmit an empty valueRequired message appears and no login is granted
O05BoundarySubmit five digits and then seven digitsBoth are rejected without verifying a truncated value
O06NegativeEnter letters, spaces or non-ASCII digit charactersInput is rejected with the six-digit format requirement
O07NegativeSubmit a well-formed but incorrect codeVerification fails and one wrong attempt is recorded
O08FunctionalCorrect the code after one failed attemptCurrent valid code succeeds while attempts remain

Time, resend and races

IDCategoryTest caseExpected result
O09BoundarySubmit at server age 179 seconds with delivery latency controlledVerification succeeds before the 180-second expiry
O10BoundarySubmit at server age exactly 180 secondsCode is expired and no login is granted
O11SecuritySet the device clock backwards and submit an expired codeServer expiry still rejects the code
O12BoundaryRequest resend at 29 seconds after issuanceNo new delivery occurs and the cooldown is explained
O13BoundaryRequest resend at 30 secondsOne new challenge code is delivered and the old code is invalidated
O14NegativeAfter successful resend, submit the previous codeOld code fails even if its original expiry has not passed
O15FunctionalSubmit the newly resent codeLogin succeeds before the new code expires
O16NegativeSimulate delivery-provider failure during resendUser sees retry guidance; the existing challenge is not silently replaced with an unusable one
O17SecuritySend two concurrent verification requests for one correct codeAt most one request consumes the challenge; no second independent login is granted
O18SecurityReuse a code after successful verificationUsed challenge cannot grant another login

Abuse protection and recovery

IDCategoryTest caseExpected result
O19BoundaryMake five wrong attempts, then submit the right codeChallenge remains locked and cannot authenticate
O20SecurityRefresh or open another tab after exhausting attemptsServer-side attempt count remains exhausted
O21SecurityResend repeatedly after locking a challengeAccount-level abuse controls prevent an unlimited fresh guessing budget
O22SecuritySubmit account A code with account B challenge identifierNeither account is authenticated by the mismatched pair
O23SecurityUse a contact-verification code on the login endpointPurpose mismatch is rejected
O24SecurityInspect test logs, URLs and analytics payloadsRaw codes are absent from those records
O25NegativeLose the network while verification is in flightUI offers recovery and checks session state before asking for another code
O26FunctionalChange the destination before requesting a new codeOld challenge cannot verify the replacement destination

Usability and delivery quality

IDCategoryTest caseExpected result
O27UIUse keyboard and screen reader to enter a code and read an errorInput purpose, focus and error are perceivable without relying on colour
O28UIDelete a middle digit in a segmented inputFocus and remaining digits permit correction without silently reordering the code
O29PerformanceMeasure stub delivery and verification separately at agreed peak loadBoth meet their separate budgets; delivery delay is not hidden inside verification timing
O30CompatibilityRepeat paste, leading-zero and expiry cases on supported mobile and desktop browsersSame verification outcome; keyboard and paste behavior remain usable

Evidence and prioritisation

Prioritise O01, O10, O14, O17 and O22: they probe success, expiry, replacement, concurrency and account binding. Record issuance time, server verification time, challenge identifier and outcome without retaining the raw code. A common mistake is checking only the countdown animation; it is the server decision that matters. For a follow-up about TOTP, explain that clock windows and seed enrolment need a separate suite. See the login cases for the surrounding session flow.

Downloads

Quick answers

Is every OTP six digits?

No. Length and character set belong to the product contract; six digits is only the fixture used here.

Does resend always invalidate the old code?

Not universally. This suite assumes it does; agree the replacement rule and test it on the server.

Sources

Want a project you can show in interviews?

The portfolio project kit walks you through testing a deliberately buggy app with Selenium or Playwright and API tests, then explaining it. The app itself is free.