checklistformsvalidationtestingaccessibility

Form testing checklist: 30+ cases people forget

A form is where the user’s data meets your system. And this is exactly where most of the “boring” bugs live: trimmed spaces, lost input, submitting twice. The good news — forms are tested by a checklist, and that checklist is reusable on any form: login, payment, profile, request.

Below — a grouped breakdown plus a ready flat checklist you can save and run.

1. Text fields

  • Spaces: leading/trailing are trimmed (or explicitly not — but deliberately); a string of only spaces doesn’t pass as “filled”.
  • Max length: input is truncated/blocked at the limit; the DB value isn’t longer; the character counter is honest.
  • Unicode and emoji: a name Ø, ideographs, 😀 — are saved and displayed without ???? and crashes.
  • RTL (Arabic/Hebrew), mixed LTR+RTL text — doesn’t break the layout.
  • Paste from clipboard: long text, text with newlines/tabs/invisible characters, formatted text.
  • Case and normalization: email/login are lowercased where needed; Unicode normalization (é as one character vs two).

2. Validation

  • Required: an empty required field is caught; the message is clear and next to the field.
  • Timing of validation: inline (on blur/input) vs on-submit — consistent; doesn’t annoy with validation on every keystroke.
  • Error messages: what’s wrong AND how to fix it, without “Error 0x0” and without blaming the user.
  • Boundary values: min/max length and value exactly at the boundary and ±1.
  • Dependent fields: “other” enables a text field; country changes the postcode/phone format.
  • Re-validation on the server: client-side checks can be bypassed — the server must validate the same thing (OWASP Input Validation).

3. Numbers and money

  • Separators: thousands/decimals by locale (1,000.50 vs 1 000,50); comma vs dot.
  • Negatives, zero, leading zeros (007), plus sign, exponent (1e9).
  • Money: rounding, cents, no float errors (0.1+0.2), currency and its format.
  • Overflow: very large number, max int, long fraction — doesn’t crash and doesn’t lose precision.
  • Non-numeric input in a numeric field: letters, spaces, special chars — rejected clearly.

4. Special fields: email, phone, date, password

  • Email: user+tag@, subdomains, long TLDs, unicode domains; not an overly strict regex (valid addresses must not be rejected).
  • Phone: international E.164 format, +, parentheses/dashes/spaces, different lengths by country.
  • Date: format by locale, boundaries (Feb 29, April 31), future/past where not allowed, time zones — see the separate dates checklist.
  • Password: complexity rules clear upfront; paste allowed (blocking paste is an anti-pattern); show/hide; very long password; edge spaces.

5. Masks and autofill

  • An input mask (card/phone/date) doesn’t get in the way of pasting and doesn’t break the cursor when editing in the middle.
  • Browser/system autofill fills fields correctly and triggers validation (a common bug — autofill, but the button is still disabled).
  • The password manager fills login/password; fields are marked with correct autocomplete attributes.

6. Submit and idempotency

  • Double click / fast repeated submit → the request goes once (button disabled, spinner). No two orders are created.
  • Enter in a field submits the form as expected (or not, if it’s a textarea).
  • Slow response: a visible loading state, can’t click again.
  • Server idempotency: a repeat of the same submit (network retry) doesn’t duplicate the record.

7. Network and states

  • Network drop at the moment of submit: clear error, the entered data is NOT lost, can retry.
  • Timeout and slow network: the form doesn’t “hang” silently.
  • Browser Back button and refresh: a warning about data loss / draft saved.
  • Re-submit after an error — no duplication (see idempotency).
  • Session expired by submit time: a clear re-login flow without losing the entered data.

8. Security

  • Special chars and injections: ' OR 1=1, <script>, templates ${} / {{}} — escaped, not executed.
  • HTML/markdown in fields isn’t rendered as markup where it shouldn’t be.
  • File upload (if any): type/size/name — a big separate topic.
  • Sensitive fields aren’t logged or cached (passwords, cards).

9. Error accessibility

  • On error, focus moves to the first invalid field; errors are associated with the field (aria-describedby).
  • An error isn’t conveyed by color alone — there’s text/icon (WCAG Error Identification 3.3.1).
  • The screen reader announces the error message (aria-live/role=alert).
  • Fields have a <label>; placeholder doesn’t replace the label.
  • Keyboard navigation and submit; visible focus.

Ready checklist (save it)

  1. Spaces are trimmed; a string of spaces ≠ filled.
  2. Max length is enforced in UI and DB; the counter is honest.
  3. Unicode/emoji/RTL are saved and displayed correctly.
  4. Paste from clipboard (long/formatted/with invisible chars) is handled.
  5. Required is caught; the message is clear and next to the field.
  6. Validation is consistent in timing (inline vs submit), not annoying.
  7. Messages explain how to fix, no codes or blame.
  8. Boundaries of min/max length and value (at the boundary and ±1).
  9. Dependent/conditional fields work.
  10. Server validation duplicates the client one.
  11. Numbers: locale separators, negatives, zero, overflow.
  12. Money: rounding, no float errors, currency and format.
  13. Email doesn’t reject valid addresses (+tag, subdomains, unicode).
  14. Phone: international formats, E.164.
  15. Date: boundaries, locale, time zones.
  16. Password: paste allowed, show/hide, rules clear, long ok.
  17. Masks don’t break paste and mid-string editing.
  18. Autofill fills and triggers validation (button doesn’t stay disabled).
  19. Double submit/Enter → one request; button disabled.
  20. Server is idempotent to a repeated submit.
  21. Network drop: error clear, input not lost, retry without duplication.
  22. Back/refresh: warning/draft.
  23. Expired session: re-login without data loss.
  24. Injections/special chars escaped, not executed.
  25. HTML in fields not rendered as markup.
  26. Passwords/cards not logged or cached.
  27. Focus on the first invalid field on error.
  28. Error not by color alone; there’s text/icon.
  29. Screen reader announces errors; there’s a label, not just a placeholder.
  30. Keyboard navigation and visible focus.

Mini test-case template for a field

For each field run: empty → spaces → minimum → maximum → over the limit → valid → invalid format → special chars → paste → autofill. This covers 90% of a field’s bugs in one pass.

Bottom line

Forms seem simple, but they’re exactly where invisible bugs accumulate that hit conversion and data. A systematic checklist by category (fields → validation → submit → network → security → accessibility) turns “I poked at it” into reproducible coverage. Save it and run it on every form.

Sources