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