Blog
Password Reset Test Cases (Complete Checklist)
Password reset test cases and a complete checklist for request, email token, expiry, reuse, and post-reset session handling in modern apps.
- password-reset
- authentication
- security
- test-cases
Password reset sits at the intersection of UX sympathy and account takeover risk. If the flow is loose, attackers reset accounts they do not own. If it is brittle, legitimate users flood support with "I never got the email" tickets. A dedicated set of password reset test cases keeps both failure modes visible instead of letting one hide behind the other.
This checklist assumes email-based reset tokens, the common web pattern, and then extends into SMS OTP and magic-link variants later in the article. Pair it with login test cases for pre- and post-authentication behavior and with how to write QA test cases for field-level quality on whatever cases you draft from this list.
Why this flow deserves its own suite
Teams often bolt a handful of reset cases onto the login suite and move on. That undersells the risk. Reset is one of the few flows where a single defect can either lock a paying customer out entirely or hand an unauthenticated party a path into someone else's account. It also touches more systems than login does: an email or SMS provider, a token store, session management, and sometimes an audit log for compliance. Treating reset as its own suite makes ownership clearer — when a mail-delivery bug and a token-reuse bug both live in one oversized login case, whoever triages the failure has to untangle two unrelated root causes from a single report.
Flow map
- Request reset (identify account)
- Notify user (email/SMS)
- Open tokenized link
- Set new password
- Session and credential invalidation
- Confirmation and next login
Test each stage independently so a mail-delay bug does not mask a token-reuse bug, and so a failing stage does not block coverage of the stages after it. Use API-level token issuance in non-production environments to reach later stages without waiting on real mail delivery every time.
Shared fixtures and safety
| Fixture | Purpose |
|---|---|
user.reset-active | Happy path |
user.reset-unknown | Unknown email behavior |
user.reset-disabled | Disabled account policy |
user.reset-sso-only | User has no local password to reset |
user.reset-mfa-enrolled | Confirms MFA is not silently bypassed by reset |
| Mail catcher / provider test inbox | Capture links without touching real inboxes |
| SMS sandbox number (if OTP supported) | Capture codes without carrier costs |
| Clock control (if available) | Expiry and clock-skew tests |
Never print raw tokens in public ticket comments, chat channels, or screenshots. Redact before attaching evidence, and prefer copying the token value into a private scratchpad only for the duration of the test.
Request stage cases
Valid account receives reset message
Expect: Success acknowledgment on UI; message delivered to the account's registered email; message contains one primary CTA link; no password in the email body.
Unknown email handling
Type: Negative / Security Expect: Response matches your anti-enumeration policy (often a generic "if an account exists…" message). Response timing should not blatantly differ from the valid-account path if uniform timing is your stated standard.
Disabled account request
Expect: Product policy decides between a silent generic response and explicit disabled-account guidance. Assert the chosen policy, and confirm no active reset token becomes usable contrary to that policy.
Rate limiting on request endpoint
Expect: Repeated requests throttle after the configured threshold; a later legitimate request can still succeed once the cooldown passes.
CSRF / authz on request API
If the site is cookie-session based, confirm the state-changing request is protected. If it is a public API, confirm abuse controls (captcha, velocity checks) are still enforced even without a session.
Multiple requests before completing the first
Type: Edge Steps: Request reset twice in a row for the same account before opening either link. Expect: Behavior matches your documented rule — either the newest token invalidates the older one, or both remain valid until one is used. Whichever you ship, the case should assert it explicitly rather than assume it.
Email content and link cases
Link points to correct environment
Staging emails must never deep-link to production, and production emails must never resolve to a staging host after an environment migration.
Link uses HTTPS
Expect: No mixed-content token leak via HTTP referrers on embedded assets (tracking pixels, logo images).
Email does not include full session cookies
Obvious in principle, still worth a quick header inspection in security-focused releases and after any change to the email templating service.
Email supports plain-text fallback
Expect: Clients that render plain text only (or block HTML by policy) still show a usable link and clear instructions, not a wall of broken markup.
Token consumption cases
Valid token opens reset form
Expect: Form accepts new password plus confirmation; shows policy hints (length, complexity) before submission, not only after a failed attempt.
Expired token rejected
Type: Edge Expect: Clear expiry message; a visible path to request a new link; the old token cannot be forced into working via a direct API call even if the UI is bypassed.
Tampered token rejected
Type: Security
Expect: A 400/403/404-style failure; no stack trace; no account enumerated beyond your stated policy.
Already-used token rejected
Type: Security Expect: A second submission with the same token fails; only the first successful reset stands, even if the second submission arrives within milliseconds of the first.
Token bound to user
Attempt to reset user A's password with user A's token but user B's email swapped into the POST body. Expect: Rejected. Token ownership is derived server-side from the token itself, never from a client-supplied identifier.
Token replayed across two open tabs
Type: Edge / Concurrency Steps: Open the same reset link in two tabs, submit different new passwords from each nearly simultaneously. Expect: Exactly one password change succeeds; the losing tab receives a clear "link already used" message rather than a false success.
SMS OTP and magic-link variants
Not every product uses emailed tokens. Adapt the token cases above and add these for SMS or magic-link flows:
| Case | Type | Expect |
|---|---|---|
| OTP expires at configured TTL | Edge | Rejected after expiry; resend available |
| OTP resend before cooldown elapses | Negative | Blocked or queued per policy, not silently duplicated |
| OTP entered with leading/trailing whitespace | Edge | Trimmed and accepted, or documented as rejected |
| Magic link opened on a different device than requested | Edge | Works if policy allows cross-device completion; otherwise a clear device-mismatch message |
| SMS delivery to a landline or VOIP number | Negative | Graceful failure, not a silent hang |
| Country-code formatting variations | Edge | Normalized before delivery |
Carrier delivery delays are common outside CI. Keep a manual smoke case around real-carrier timing for release sign-off even if automated suites rely on a sandbox number.
Password policy cases on reset form
| Case | Expect |
|---|---|
| Too short | Rejected |
| Missing required complexity | Rejected per policy |
| New password equals old (if disallowed) | Rejected |
| Confirmation mismatch | Rejected |
| Breached password blocked (if integrated) | Rejected with guidance |
| Password manager autofill into both fields | Accepted like manual entry |
| Paste disabled on confirmation field (legacy pattern) | Should not be disabled; verify UX has moved on |
| Extremely long password (near max length) | Accepted up to documented limit, rejected beyond it |
If a breach-check integration adds latency, verify the UI communicates "checking…" rather than appearing frozen, and that a provider timeout fails open or closed according to your security team's decision — not by accident.
Post-reset session and login
Success confirmation
Expect: User is guided to login or auto-logged in per design — document which, since both are defensible and testers should not guess.
Old password no longer works
Priority: High Expect: Immediate invalidation, not eventually consistent without disclosure to the user.
Existing sessions revoked or retained per policy
Many enterprise apps revoke all sessions on reset. Expect: that behavior if it is claimed in security documentation. If sessions remain active elsewhere, confirm that is intentional and communicated, not an oversight.
MFA re-challenge after reset
For MFA-enrolled accounts, Expect: the first login after reset still requires the existing second factor unless the product explicitly resets enrollment too. A reset flow that quietly drops MFA is a severity-defining bug.
Concurrent reset requests
Two outstanding tokens: define whether the newest invalidates the older one, or both work until used. Test the rule you ship, not the rule that sounds safest in the abstract.
Admin-initiated resets
Support triggers reset email
Expect: Audit log entry created; same token rules apply as the self-service path — no special "support bypass" that skips expiry or single-use enforcement.
Temporary password pattern (legacy products)
If used: forced change on next login; temporary password expires; transmission channel is secured (not plaintext chat or unencrypted email when avoidable).
Cross-device and clock-skew edge cases
Reset flows frequently break at the seams between devices and clocks — see edge case testing for the general discipline this borrows from.
- Request on phone, complete on desktop. If cross-device completion is allowed, confirm the desktop session ends up correctly authenticated, not silently still logged out.
- Client clock several minutes fast or slow. Token expiry should be evaluated server-side; a client miscalculating "expires in 10 minutes" is a display bug worth catching, not a security bug.
- Daylight-saving transition during a token's lifetime. Confirm expiry math uses UTC or a documented timezone consistently rather than local wall-clock arithmetic that can shift by an hour.
Accessibility and UX checks
- Errors are associated with their fields, not floating in an unrelated page region
- Token error pages offer a next step, not a dead end
- Password reveal toggles do not leak the plaintext value into analytics events or session replay tools
- Screen readers announce success and error states without requiring a page refresh
Common defects found in password reset audits
| Defect pattern | Why it slips through |
|---|---|
| Token logged in plaintext in application logs | Logging middleware captures full query strings by default |
| Reset link reused across password managers as a bookmark | Nobody tested "save this link and click it twice next week" |
| Old sessions survive reset because revoke logic only touched one service | Multi-service auth without a shared revoke event |
| Rate limit counted per IP instead of per account, locking out shared-office users | Threat model assumed residential IPs only |
Reviewing a short list like this before a release often surfaces more real risk than another dozen "empty field" variants.
Automation notes
Automate API-level token creation only through test harnesses that exist in non-production. Avoid scraping real inboxes in CI when a mail API or catcher is available — it is slower and flakier for no added confidence.
// illustrative: exercise the reset lifecycle without a real inbox
const { token } = await testSupport.issueResetToken(userId);
await api.post("/reset/confirm", { token, newPassword: "N3w-Passphrase!" });
await expect(api.post("/reset/confirm", { token, newPassword: "Another1!" })).rejects.toMatchObject({
status: 409,
});Combine reset abuse cases with broader negative test cases when building an auth security pack for an audit or a pen-test readiness review.
Promote the cases above into your durable regression test cases core once they have proven stable, rather than re-deriving them from scratch every release.
Suggested execution sets
| Trigger | Cases |
|---|---|
| Copy change on reset email | Content + link environment check |
| Token service refactor | Valid, expired, reused, tampered |
| Session service change | Old password invalid + session revoke |
| MFA rollout | MFA re-challenge after reset added to core set |
| Full auth epic | Entire checklist + login smoke |
Coverage philosophy: Basic vs Deep. A ready-made structure for these cases lives in the QA test case template. Assisted drafting plans: Pricing. Product setup: Docs.
Complete checklist (printable)
Request
- Valid user receives message
- Unknown email follows enumeration policy
- Disabled user policy verified
- Rate limit verified with a safe fixture
- Repeated requests before completion follow the documented token rule
Token
- Valid token works once
- Expired token fails
- Tampered token fails
- Used token fails
- Cross-user token fails
- Two-tab replay resolves to exactly one success
Password
- Policy enforced
- Confirm mismatch caught
- Old password dead after success
- Password manager autofill works normally
Session
- Post-reset login path works
- Session revoke policy verified
- MFA re-challenge still required if enrolled
Ops
- Emails point to correct environment
- Tokens not logged in application logs
- Support runbook exists for "email not arriving"
- SMS/magic-link variants covered if shipped
FAQ
Should reset require knowing the old password?
Self-service email reset usually does not. "Change password while logged in" is a different suite — keep them separate so a bug in one does not get buried in the other's report.
How long should tokens live?
Follow the security design, often minutes to a few hours. Test expiry at the configured value, not a textbook number pulled from a blog post.
Do we test deliverability?
Spot-check spam placement in major providers for branded launches; day-to-day QA uses mail catchers instead of real inboxes.
What about account recovery without email access?
That is identity proofing and support-process testing — out of band from this checklist, and usually owned by a different runbook entirely.
Final checklist
- Stages tested independently (request, token, set, session)
- Enumeration policy consciously verified
- One-time token semantics enforced, including concurrent-tab replay
- Old credentials invalidated immediately
- Session policy matched to security documentation
- MFA re-challenge confirmed for enrolled accounts
- Admin/support path audited
- SMS or magic-link variants covered if shipped
- Automation avoids production inboxes
- Linked to login suite without duplicating all login cases
- Logs scrub tokens
- Support can diagnose undelivered mail or SMS
CTA — turn auth recovery stories into a gated suite
Reset epics often bury token rules in prose. Pull acceptance criteria into structured reset cases with QA Workflow Assistant, then validate expiry, reuse, and cross-device behavior against this checklist before exposing the flow on production domains. Wire environments using Docs.
Related articles
25 Login Test Cases Every QA Engineer Should Know
A practical set of 25 login test cases covering valid access, failures, lockouts, sessions, MFA, and SSO-ready checks for modern QA teams.
August 3, 2026 · 11 min read
Negative Test Cases: Examples Every QA Engineer Should Use
Learn how to design negative test cases with practical examples for validation, authorization, state conflicts, and API failures that catch real defects.
August 8, 2026 · 12 min read
Shopping Cart Test Cases with Real Examples
Shopping cart test cases with real examples for quantity rules, stock, discounts, guest carts, and checkout handoff for ecommerce QA teams.
August 6, 2026 · 12 min read