Untestable Requirements: 5 Phrases to Flag
Requirements problems account for roughly half of all software defects. Studies putting a number on it land between 50% and 60% depending on who is measuring and which projects they sampled, and the split inside that figure matters more than the figure: about half of requirements defects come from wording that is unclear, ambiguous, or wrong, and the other half from requirements nobody wrote down at all.
Every tester who has sat through a UAT post-mortem knows the shape of it. Nobody wrote bad code. Two people read the same sentence differently. That sentence is usually findable before a line gets written, and these are the five phrasings worth searching for first.
"Should be fast"
Also appearing as responsive, performant, quick, and without noticeable delay. None of these can fail a test, because no result contradicts them. A tester who files a bug against "should be fast" gets asked how fast it needs to be, and the conversation that should have happened during refinement happens during regression instead.
Replace it with three things: a number, a percentile, and a measurement point. "The search results render within 400ms at the 95th percentile, measured from request sent to first row painted." Now a build can fail.
The percentile matters more than teams expect. An average hides the tail, and the tail is what your users complain about.
Free and open sourceCasely writes these cases for youAttach a spec and one file of your team's existing test cases in Claude. Casely copies your columns, names the gaps it found in the spec, and exports a single Excel file your tracker imports in one pass.Read the install docs"Handle errors gracefully"
This one is worse than vague, because it reads like a requirement about error handling while specifying nothing about any error.
Ask which errors. Then ask, for each one, what the user sees, what the system logs, whether the operation retries, and what state the data ends in. A payment timeout that shows a friendly message and silently double-charges handled the error gracefully by this requirement's standard.
"User-friendly" and "intuitive"
Nobody can test these, and everybody assumes their own reading is the obvious one. Push for the behaviour underneath. If the intent is that a new user completes signup without help, write that: a first-time user completes signup in under two minutes without opening documentation. That version can be observed. You can even run it as a usability session with five people and get an answer.
"Etc." and "and so on"
A list that trails off is a list the author stopped writing. Every item they did not name is an item nobody will test and nobody will build.
"The system supports PDF, DOCX, etc." leaves you guessing about ODT, RTF, and the scanned JPEG your largest client uploads. Close the list, or state the rule that decides membership.
"As needed" and "where appropriate"
These push a decision from the person who understood the problem onto whoever implements the ticket, six weeks later, with no context. "Fields are validated where appropriate" means the validation will be inconsistent and the inconsistency will surface as a bug report from a customer.
What gaps never announce themselves?
Vague wording at least looks suspicious on the page. Two other requirement failures hide better.
Contradictions between sections. Section 3 says a session expires after 30 minutes of inactivity. Section 11, written by someone else in a different sprint, says the cart persists for 24 hours. Both are testable. They cannot both hold. Long documents accumulate these, and a reader working through the file linearly rarely catches them, because the two statements sit forty pages apart.
Missing error paths. Specifications describe what happens when things work. The failure branches live in the author's head: what if the upload is interrupted at 80%, what if the third-party API returns a 500, what if the user's session expires mid-form. These absences are the single most common gap in the specs we see, and they are the ones that produce production incidents rather than cosmetic bugs.
What twenty-minute review pays for itself?
Before writing a single case, run the document through four passes.
- Search for the vague words. Every instance either gets a number or a note that you are testing your own interpretation.
- List every external system, every timeout, and every user-initiated cancel. For each one, find the paragraph describing the failure. Most will not exist.
- Build a two-column table of every rule you find, one row per rule, sorted by the entity it constrains. Contradictions surface when the two statements sit next to each other instead of forty pages apart.
- Write down every assumption you made to fill a gap. Send that list to the product owner. This list is the deliverable, and it is usually more valuable than the first draft of the test plan.
An ambiguity caught in this pass costs one conversation. The same ambiguity caught in UAT costs a sprint of rework plus a regression cycle, and the argument about whether it was ever in scope.
Why does this stay a human skill?
Reading a spec for contradictions is pattern matching across a long document, which machines do well. Deciding that a missing error path matters enough to block a release is a judgment about risk, users, and what your company can survive, which they do not.
Use the tooling for the first part. Keep the second.