← Back to blog
Testing FundamentalsBy

UAT in Software Testing: Who Runs It, What It Catches, and Why It Keeps Slipping

Every other kind of testing asks whether the software works. UAT asks whether it does the thing you actually promised.

There is a category of bug that no amount of engineering rigour will find. The types check. The unit tests pass. Code review approves it. It ships, it renders, it calculates, and it is wrong — because somewhere a number in the code stopped matching a number in an agreement.

Correct and wrong at the same time

A cart with a $62.00 camping stove. The store’s stated policy, agreed with merchandising and printed on the home page, is free shipping on orders over $100.

Threshold set to $50
A cart with a $62.00 subtotal showing Free shipping, despite a stated $100 free-shipping threshold

Subtotal $62.00 · Shipping: Free

Threshold set to $100
A cart on the correct build with a $62.00 subtotal and a $9.95 shipping charge below the $100 free-shipping threshold

Subtotal $62.00 · Shipping $9.95

Somebody typed a different number, or an old value survived a merge, or the rule changed in a conversation that never reached the ticket.

Consider what would have caught this. Not the type checker — $50 is a perfectly valid number. Not a unit test — it would assert whatever constant the code contains. Not QA — the cart calculates, renders and checks out correctly. Not monitoring, not error tracking, not code review unless the reviewer happened to remember the policy.

Nothing is broken. The software does exactly what it was told to do. It was told the wrong thing, and the only person who can see that is someone who knows what was promised.

What UAT is

User acceptance testing verifies that software does what the business agreed it would do. It is the final gate before release, and what makes it distinct is the standard it judges against: not a technical specification, but the acceptance criteria somebody wrote down when the work was scoped.

The run that caught it

We wrote the criterion the way merchandising would state it — as a sentence about a customer, not a test about a system — and pointed it at the broken build.

Real Diffie run · demo.diffieai.comTest failed
What we asked for

As a customer, add the Titanium Pocket Stove ($62) to my cart. Because my order is under $100, I should be charged $9.95 shipping, not free shipping.

What came back

The agent’s own plan came back as “open the cart and verify subtotal, paid shipping, and absence of Free shipping text”. It derived the negative assertion by itself — and that absence check is the one hand-written acceptance tests most often miss.

The specification is the acceptance criterion, verbatim. Nobody translated it into a test — which is the property that lets the person who owns the rule also own the check.

UAT vs QA testing

The two get conflated constantly, and the distinction is simple: QA asks whether the software works. UAT asks whether it does the right thing.

A QA engineer checking the cart above would test that the total recalculates when quantity changes, that the shipping line updates when items are removed, that the number formats correctly in every locale. All valuable. None of it involves knowing that the threshold was supposed to be $100, because that is not a property of the software — it is a property of the agreement.

Who should actually run it

The person who owns the rule: a product manager, a domain expert, an operations lead, occasionally a real customer in a beta programme.

It should not be the engineer who built the feature, for the reason it is never the author who catches their own typo — they will test the behaviour they implemented, because that is the behaviour in their head. And it is frequently not QA, who know the system deeply and the commercial agreement barely.

This creates the practical problem that defines UAT in most organisations. The people qualified to run it have another full-time job, so UAT gets squeezed by whoever is busiest at the end of a release cycle — precisely when a release is most likely to contain something nobody agreed to.

Writing criteria that can actually be tested

Most UAT failures trace back to criteria too vague to check. “Shipping should be reasonable for small orders” cannot fail a test, because it cannot pass one.

  • A specific number or state. “Orders of $100.00 or more ship free”, not “large orders ship free”. The boundary is the part that breaks.
  • A stated negative. “Orders under $100.00 are charged $9.95 and must not show ‘Free’”. The failure above was on the negative side of the rule, and criteria that only state the positive case never catch it.
  • An observable outcome. Something a person could point at on screen. If verifying it requires reading the database, it is not an acceptance criterion.

Always pick a value between the two plausible thresholds. A $500 order passes under both the correct rule and the broken one. A $62 order distinguishes them. This single habit catches most off-by-one and wrong-constant acceptance bugs.

Running a UAT cycle

  • Test against production-like data. Acceptance bugs hide in real data shapes. A catalogue of three seeded products will not reveal a threshold problem.
  • Test the journey, not the screen. Acceptance criteria describe what a person is trying to accomplish. Verify the whole path, in order, as a user would walk it.
  • Record the expected value before you look. Writing “shipping should be $9.95” down first prevents the strongest bias in manual UAT: seeing a number and deciding it looks about right.
  • Log failures against the criterion, not the code. “Free shipping threshold is $50, agreed criterion is $100” is actionable. “Shipping is wrong” is not.
  • Re-run the whole set on every release. Acceptance criteria do not expire. Last quarter’s rules are still rules.

Automating the stable half

That last point is where manual UAT collapses. A rule agreed in March needs verifying in April, May, and every release after — but nobody schedules a product manager to re-check free-shipping thresholds forever. So in practice each criterion is checked once, near the release that introduced it, and never again.

Which means the regression that reintroduces a violated rule six months later will not be caught by UAT. It will be caught by a customer.

Automating UAT does not remove the human from acceptance testing. It removes the human from the repetition. Judging whether a new feature feels right still needs a person. Re-checking that a rule agreed nine months ago still holds does not.

What stays manual

Some acceptance work should never be automated, and pretending otherwise is how teams end up with a green pipeline and an unusable product:

  • First contact with a new feature — does this feel right, is the flow sensible.
  • Anything involving judgement: tone, clarity, whether an error message helps.
  • Exploratory work where the value is the questions a person thinks to ask.
  • Criteria still being negotiated. Automate a rule once it has settled.

The split is clean. Judgement stays with people, repetition goes to machines. UAT has historically failed because those two were bundled together and the whole bundle got dropped whenever a deadline moved.

Frequently asked questions

What is UAT in software testing?

User acceptance testing verifies that software does what the business agreed it would do. It is the last check before release, and it is judged against the acceptance criteria rather than against a technical specification. Working code that violates an agreed rule fails UAT.

Who should run UAT?

The person who owns the requirement — a product manager, a domain expert, an operations lead, sometimes an actual customer. Not the engineer who built it, and often not QA. The point of UAT is that someone who knows what the business promised checks whether it was delivered.

What is the difference between UAT and QA testing?

QA asks whether the software works correctly. UAT asks whether it does the right thing. A feature can pass every QA check — no crashes, no errors, correct API responses — and still fail UAT because it implements a rule nobody agreed to.

What is the difference between UAT and end-to-end testing?

End-to-end testing is a technique: drive the whole system through a real browser. UAT is a purpose: confirm the business rules hold. Most UAT is performed as end-to-end tests, but an E2E test written by an engineer to check a code path is not UAT.

Should UAT be automated?

The acceptance criteria that stay stable should be, because they need re-checking on every release and manual UAT is the first thing dropped when a deadline moves. Exploratory acceptance work — a domain expert poking at a new feature to see if it feels right — cannot and should not be automated.

Why does UAT always get squeezed?

Because it sits at the end of the schedule and depends on people whose main job is something else. When a release slips, UAT is the phase with the least institutional defence. Automating the stable criteria is the only reliable way to keep the check when the calendar gets tight.

Keep reading

Turn acceptance criteria into tests

Write the rule the way the business states it. Diffie runs it in a real browser on every release, so criteria that used to be checked by hand get checked every time.