Form validation test case generator
Pick your form's fields and get the test cases for each — with the exact value to paste and what should happen. Free, no signup.
1. Your form's fields
Click a field to change its type, name or limit.
2. Your test cases
63 across 4 fields
| Case | What it checks | Expected | Value |
|---|---|---|---|
| Standard addressValid | The happy path is accepted and the account is created | Accept | a.hansen@example.com |
| Plus-addressingValid | A + tag is valid per RFC 5321 — rejecting it locks out Gmail power users | Accept | qa.tester+signup1@example.com |
| Subdomain + multi-part TLDValid | Deep domains are accepted; naive regexes stop at one dot | Accept | user@mail.example.co.uk |
| Mixed caseValid | The address is accepted and matched case-insensitively at login | Accept | QA.Tester@Example.COM |
| Apostrophe in the local partValid | Real addresses contain apostrophes — accepted and stored unescaped | Accept | o'brien@example.com |
| EmptyBoundary | Required-field validation fires and the message names this field | Reject | (empty) |
| Exactly the limit (254)Boundary | A value at the documented maximum is accepted and stored whole | Accept | aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa…254 |
| One over the limit (255)Boundary | Over-length input is rejected, not silently truncatedA maxlength attribute hides this in the UI — check what actually reaches the database. | Reject | aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa…255 |
| 64-character local partBoundary | The RFC maximum local part is accepted | Accept | aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa…76 |
| 65-character local partBoundary | One over the RFC local-part maximum is rejected | Reject | aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa…77 |
| Leading and trailing spacesBoundary | The value is trimmed before validation, or rejected with a clear messageSilently storing the untrimmed value is the bug — the user then can't log in. | Decide & be consistent | user@example.com |
| No @ symbolMalformed | A plain string is rejected | Reject | notanemail.com |
| Two @ symbolsMalformed | Multiple @ characters are rejected | Reject | user@@example.com |
| No domainMalformed | A missing domain is rejected | Reject | user@ |
| No local partMalformed | A missing local part is rejected | Reject | @example.com |
| No TLDMalformed | A bare hostname is rejected | Reject | user@example |
| Trailing dotMalformed | A dangling dot in the domain is rejected | Reject | user@example. |
| Space inside the addressMalformed | Embedded whitespace is rejected, not stripped | Reject | us er@example.com |
| Accented local partSpecial characters | The address survives UTF-8 round-tripping if accepted | Decide & be consistent | josé@example.com |
| Internationalised domainSpecial characters | An IDN domain is accepted or rejected consistently — never mangledIf accepted, confirm the confirmation email actually sends. | Decide & be consistent | user@exämple.com |
| Case | What it checks | Expected | Value |
|---|---|---|---|
| Meets the policyValid | A compliant password is accepted and the account is usable afterwards | Accept | Correct-Horse-9 |
| EmptyBoundary | Required-field validation fires and the message names this field | Reject | (empty) |
| Exactly the limit (64)Boundary | A value at the documented maximum is accepted and stored whole | Accept | aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa…64 |
| One over the limit (65)Boundary | Over-length input is rejected, not silently truncatedA maxlength attribute hides this in the UI — check what actually reaches the database. | Reject | aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa…65 |
| One characterBoundary | The minimum-length rule fires and states the minimum | Reject | a |
| 1,000 charactersBoundary | A very long password is capped — unbounded input makes hashing a denial-of-service vector | Reject | aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa…1000 |
| Leading and trailing spacesSpecial characters | Spaces are preserved, not trimmed — trimming on signup but not on login locks the user outThe classic version of this bug: signup trims, login doesn't. | Accept | spaced pass |
| Spaces onlySpecial characters | A whitespace-only password is rejected | Reject | (8 spaces) |
| EmojiSpecial characters | Multi-byte characters survive hashing and log the user back inIf accepted, the real test is logging in again afterwards. | Decide & be consistent | p@ssw😀rd9 |
| Non-Latin scriptSpecial characters | Unicode is byte-safe end to end | Decide & be consistent | Пароль-2026 |
| Apostrophe and quotesSpecial characters | Quote characters are stored and compared correctly | Accept | O'Brien"9x |
| Well-known passwordMalformed | A breached/common password is refused if you claim a strength policy | Reject | password123 |
| Sequential digitsMalformed | Trivial sequences are refused by the strength check | Reject | 12345678 |
| Tab and newlineMalformed | Control characters are rejected or normalised — never stored raw | Reject | pass word
|
| Case | What it checks | Expected | Value |
|---|---|---|---|
| Ordinary nameValid | The happy path stores and renders unchanged | Accept | Anna Hansen |
| ApostropheValid | The name saves and renders as typed — no escaping artefacts like O'Brien | Accept | Siobhán O'Brien |
| Hyphen and spaceValid | Compound names are accepted | Accept | Anne-Marie de la Cruz |
| Single characterValid | One-letter names are valid — a min-length of 2 is a real bug for many users | Accept | O |
| EmptyBoundary | Required-field validation fires and the message names this field | Reject | (empty) |
| Exactly the limit (255)Boundary | A value at the documented maximum is accepted and stored whole | Accept | aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa…255 |
| One over the limit (256)Boundary | Over-length input is rejected, not silently truncatedA maxlength attribute hides this in the UI — check what actually reaches the database. | Reject | aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa…256 |
| Leading and trailing spacesBoundary | The stored value is trimmed | Decide & be consistent | Anna Hansen |
| AccentsSpecial characters | Latin-1 characters survive storage, search and export | Accept | Ñoño Ångström |
| CJK charactersSpecial characters | Non-Latin scripts render correctly in every view, not as boxes | Accept | 李伟 |
| Right-to-left scriptSpecial characters | RTL text does not break the layout of the list or table it appears in | Accept | مرحبا |
| EmojiSpecial characters | 4-byte characters are stored intact — a latin1 column truncates here | Decide & be consistent | Anna 😀 |
| Double quotesSpecial characters | Quotes survive round-tripping through JSON, CSV export and the UI | Accept | "Anna" |
| Angle bracketsSpecial characters | Markup characters are escaped on output rather than renderedThe value should come back out as typed — literally, with the tags visible. | Accept | Anna <b>Hansen</b> |
| Digits onlyMalformed | A numeric-only name is rejected if your rules say so — decide, don't drift | Decide & be consistent | 12345 |
| Tab and newlineMalformed | Control characters are stripped or rejected | Reject | Anna Hansen
|
| Case | What it checks | Expected | Value |
|---|---|---|---|
| E.164Valid | The canonical international format is accepted | Accept | +14155552671 |
| National format with punctuationValid | Brackets, spaces and dashes are normalised rather than rejected | Accept | (415) 555-2671 |
| Digits onlyValid | An unformatted number is accepted and normalised for storage | Accept | 4155552671 |
| Non-US country codeValid | Numbers outside the default country are accepted (length differs by country) | Accept | +442071838750 |
| EmptyBoundary | Required-field validation fires and the message names this field | Reject | (empty) |
| Exactly the limit (20)Boundary | A value at the documented maximum is accepted and stored whole | Accept | 99999999999999999999 |
| One over the limit (21)Boundary | Over-length input is rejected, not silently truncatedA maxlength attribute hides this in the UI — check what actually reaches the database. | Reject | 999999999999999999999 |
| Three digitsBoundary | A too-short number is rejected | Reject | 123 |
| LettersMalformed | Alphabetic input is rejected with a format message | Reject | 555-CALL-NOW |
| Unassigned area codeMalformed | A structurally plausible but impossible number is rejected | Reject | +1-000-000-0000 |
| Impossible country prefixMalformed | An out-of-range country code is rejected | Reject | +999999999999999 |
| Non-Latin digitsSpecial characters | Arabic-Indic digits are normalised or rejected — never stored as-isCommon on Arabic-locale keyboards; silently storing them breaks SMS. | Decide & be consistent | ٤١٥٥٥٥٢٦٧١ |
| EmojiSpecial characters | Non-numeric characters are rejected | Reject | 📞4155552671 |
Three steps, then keep the set
- Step 1
Match your form
Set each field's real limit. A 40-character name field gets 40- and 41-character cases, not generic ones.
- Step 2
Work down the table
Copy the value, paste it, compare against the expected column. Invisible values — empty, spaces, a 256-character run — are labelled but copy exactly.
- Step 3
Keep the set
Export CSV or JSON, or copy the Markdown table into a Jira ticket or a pull request so the next person runs the same checks.
Stop pasting them one at a time
These cases come from the test-data modes in Fillr — a Chrome extension that fills any web form with data you control. Save the form once, set a rule per field, and fill it with boundary values, malformed input, or your own spreadsheet rows, one click at a time.