Operations
What a Demo Hides: How to Run UAT as a Founder
By Better Software · Sat Sep 12 2026 · 12 min read
The demo looks clean. Every screen loads. The engineer driving it knows where to click, what data to enter, and which edge cases to avoid. You say it looks good, and the milestone moves forward.
That is not user acceptance testing. That is a guided tour of the happy path.
If you are the non-technical person responsible for accepting the work, your job is harder than it looks: you are not trying to prove the code is good. You are trying to prove the product does what your business agreed it would do, in the conditions your customers or staff will actually face. And you need to know where your judgment ends, because some things cannot be accepted by clicking around at all.
This is the difference between a demo that reassures you and an acceptance process that protects you.
What user acceptance testing actually is
User acceptance testing is the final check before release in which the people who represent the business use the software the way a real customer or employee would, against written criteria agreed in advance, and accept it only when those criteria pass.
That definition matters because it draws a line between three different questions:
- Can the software be operated?
- Does it behave correctly as built?
- Does it do what the business agreed it must do?
UAT answers the third question. Not the second. Not the first.
UAT vs QA: who is testing what
QA asks whether the build works as built. It is about correctness, coverage, edge cases, automation, regression, and whether the implementation holds together technically.
UAT asks whether the software does what was agreed for the business. It is about outcomes: can a customer sign up, can a staff member approve a claim, can a payment actually move, can a manager see the right record.
They are not interchangeable. The tester, the environment, and the standard are different. QA is a technical verification process. UAT is a business acceptance decision.
That is why the common internet advice falls short for founders: it assumes a QA department, a test manager, a traceability matrix, and a budget for test tooling. If you are the one signing off, you need a process you can run yourself.
Why acceptance is a business decision, not a technical one
You are not being asked to judge the code. You are being asked to decide whether the business risk is low enough to proceed. That means you can validate business correctness, but you cannot infer technical readiness from a clean click-through.
A product can demo beautifully and still fail when real users arrive, real volumes hit, or real credentials, permissions, and integrations come into play. Acceptance exists to expose that gap before money changes hands or a release goes live.
The three gates between “it works on my machine” and “we are live”
Use this framework: Three Gates. Nothing is accepted until all three pass.
Gate 1: Engineering QA — the team’s own verification
This is the team’s job. They verify the code, catch regressions, and prove the build behaves as intended in a controlled environment. If they do not have automated tests, enforced coverage, or a staging environment that mirrors production, this gate is weak no matter how polished the demo looks.
Gate 2: Founder acceptance — you, against written criteria, on realistic data
This is your gate. You check the business journeys that matter, using realistic data, and compare the actual result with the agreed acceptance criteria. This gate should be short if the engineering is solid. If it takes days of hunting for defects, you are being used as the QA function.
Gate 3: Production readiness — what the engineering lead certifies, and you cannot
Some things are outside your ability to verify by clicking. You need a separate production-readiness certification from the engineering lead covering the technical conditions that make a release safe.
Plainly: no single gate substitutes for another. A green demo is not engineering QA. A clean UAT session is not production readiness. A production-readiness note is not acceptance of business fit.
Rule: nothing is accepted until engineering QA passes, founder acceptance passes, and production readiness is certified.
Before you test: write criteria a non-technical person can judge
If the criteria are vague, the discussion becomes subjective. If they are written badly, you will end up arguing taste instead of outcome. Good acceptance criteria are observable.
The format: as a [user], I can [action], and [observable result]
Use a simple structure:
- As a customer, I can submit a support request, and I receive a confirmation number within 5 seconds.
- As a finance user, I can approve an invoice, and the status changes to Approved and appears in the audit log.
- As a clinician, I can edit a patient note, and the updated version is visible to authorized users only.
Notice what is missing: internal implementation details. You do not need to know how the system stores the record. You need to know what must be true afterward.
What is in scope for this release, and what is explicitly out
Write both lists. Scope is not just what you are testing; it is what you are not testing yet.
This prevents a common failure mode: someone accepts a release because they saw a feature work, then later discovers that adjacent functionality was assumed but never included.
Agree severity levels in advance: blocker, high, medium, low
Severity is not the same as annoyance. Agree the labels before you start:
- Blocker: prevents release or core use
- High: major business impact, but a workaround may exist
- Medium: visible problem or friction that does not stop use
- Low: cosmetic or minor issue
Agree the acceptance bar in advance
A sensible default is:
- Zero blockers
- Zero highs
- Mediums listed and consciously accepted
Without this bar, “looks good” becomes a moving target after the fact.
Running your acceptance: journeys, not features
Do not test a menu. Test a journey. A real user never experiences your product as a feature inventory; they experience it as a sequence of actions that either completes the job or does not.
Write the five to fifteen journeys that matter, per user type
For each user type, list the end-to-end journeys that drive the business outcome. For example:
- New customer signs up and completes onboarding
- Manager creates an approval and sends it to the right person
- Ops user exports a report and matches it to source records
- Patient or client updates details and sees the right confirmation
Keep the list short enough to finish, but broad enough to cover the business-critical flows.
Use realistic data, not test@test.com
Realistic data surfaces real failure modes. Use:
- Long names
- Missing fields
- Duplicate records
- Odd dates and time zones
- Real volumes, not one perfect record
Test data that looks too clean is often the reason a product passes UAT and fails in the wild.
Verify the consequence, not the confirmation screen
The screen says the payment succeeded. Did the money actually move? The app says the invite was sent. Did it arrive in the inbox? The UI says permissions changed. Can that user now see or not see what they should?
Acceptance is about outcomes, not reassurance.
Walk the unhappy paths deliberately
Happy-path testing is necessary, but it is not enough. You also need to force the product into predictable failure conditions:
- Refresh mid-flow
- Use the back button
- Double-submit
- Open an expired link
- Enter the same email twice
- Lose connectivity
- Abandon a flow and return tomorrow
These are not edge cases in practice. They are normal user behavior.
Test permissions across user types
In a multi-user or multi-tenant product, this is often the difference between a safe release and an expensive incident. Check whether customer A can see customer B’s data. Check role boundaries. Check admin vs standard user vs read-only access.
In fintech, healthcare, HR, and similar domains, a permissions failure should block acceptance immediately.
Test on the devices your customers actually use
If your customers will use mobile Safari, a corporate laptop, or a locked-down browser, test there. A product that works in your preferred browser but breaks in the customer’s environment is not accepted.
Drive it yourself, and do not let the team narrate
The moment the engineer starts explaining every click, you are back in a demo. You need enough context to test, not a guided performance.
If you get stuck, that is useful information. Confusion is a signal. A good product should let a non-technical acceptor complete the core journeys without hand-holding.
Recording what you find: PASS, FAIL, FRICTION, QUESTION
The fastest way to keep acceptance objective is to separate what happened from what you think about it.
Why four buckets beat two
Use four buckets:
- PASS: criterion met
- FAIL: criterion not met
- FRICTION: it works, but the experience is clumsy, confusing, or risky
- QUESTION: something is unclear and needs clarification before acceptance
This matters because it keeps “broken” separate from “not what I wanted.” It also stops scope changes from being disguised as defects.
What a usable report contains
For every issue or note, capture:
- The journey or criterion
- Steps taken
- Expected result
- Actual result
- Severity
- Evidence: screenshot, video, or note
Do not rely on memory. Do not rely on “it was weird.” Make the record specific enough that someone else can retest it.
Retest the fix yourself
A screenshot saying “fixed” is not a retest. If a defect matters enough to record, it matters enough to verify again in the actual flow after the fix lands.
What UAT can never tell you
This is the boundary most pages leave out. Clicking around can validate business behavior, but it cannot certify the technical foundations that keep the system safe, recoverable, and owned.
Automated test coverage and whether it is enforced
You cannot tell, by clicking, whether the engineering team has meaningful automated tests, whether those tests run in the pipeline, or whether coverage is enforced.
CI/CD and whether a deploy can be rolled back
You cannot tell whether the release process is repeatable, whether deploys are scripted, or whether a bad release can be rolled back cleanly.
Observability and logging
You cannot tell whether the team will know about a failure before customers do, or whether logs will contain enough signal to diagnose it quickly.
Backups and whether a restore has actually been tested
A backup existing is not the same as a tested restore. If the team cannot prove restore works, you do not know what happens when data is lost.
Database migrations, security, and access review
You cannot validate migration safety, security posture, or access controls by clicking through a UI.
Ownership: repository, cloud accounts, credentials, third-party accounts
You also cannot infer who owns the software stack. If the repository, cloud accounts, or third-party credentials are not clearly controlled by the customer, that is a separate issue from acceptance and must be resolved explicitly.
Ask for a production-readiness certificate covering, at minimum:
- Automated tests run successfully
- Coverage expectations are met or consciously waived
- Deploy and rollback are tested
- Observability/logging is in place
- Backups and restores are verified
- Database migration path is safe
- Security and access review are complete
- Ownership of code, accounts, and credentials is documented
Why good engineering makes your acceptance short
When the team has automated tests, enforced coverage, CI/CD, and a staging environment that mirrors production, acceptance becomes what it should be: a short check that the business intent survived implementation.
Without those foundations, UAT turns into an open-ended bug hunt. You are no longer the person accepting the work. You are doing the QA team’s job at your own expense.
That is the hidden cost of a demo-grade codebase: it can be made to look done before it is actually safe to accept. The easier the demo, the more carefully you need to test the real journeys, the real data, and the real consequences.
Tying sign-off to milestones without making it adversarial
Sign-off should be written, criterion by criterion, with known issues listed clearly. The goal is not to create conflict. The goal is to create a record of what passed, what remains open, and what you knowingly accepted.
What a fair sign-off email looks like
Keep it plain:
We have completed user acceptance testing for the agreed scope. The following criteria passed: [list]. The following items remain open: [list]. We are accepting the release subject to [conditions, if any]. Please confirm production readiness certification for the items outside UAT, including test coverage, rollback, observability, backups, access control, and ownership.
This makes the decision explicit and removes ambiguity later.
A one-page acceptance checklist you can reuse every release
Before testing
- Acceptance criteria are written and agreed
- Scope in and scope out are documented
- Severity levels are agreed
- Acceptance bar is set
- User types and journeys are listed
- Realistic data is prepared
- Devices and browsers are confirmed
During testing
- Test journeys, not features
- Verify the consequence, not just the confirmation screen
- Test unhappy paths deliberately
- Check permissions across user types
- Record each item as PASS, FAIL, FRICTION, or QUESTION
- Capture evidence for every issue
Before accepting
- All blockers are resolved
- All highs are resolved
- Mediums are reviewed and consciously accepted
- Questions are answered
- Production-readiness certificate is received
- Ownership of code, accounts, and credentials is clear
The practical answer to the usual UAT questions
What are the four types of acceptance testing? In practice, people often mean user acceptance testing, operational acceptance testing, contract acceptance testing, and regulatory acceptance testing. As a founder, you do not need to master the taxonomy to make a good decision; you do need to know that business acceptance and production readiness are different.
Is UAT part of SDLC? Yes, but it sits near the end, after the build has been verified by the team and before release is finalized. It is the point where the business decides whether the product is ready to move forward.
Who performs UAT testing? The people who represent the business: founders, operators, product owners, client stakeholders, or designated end users. Not the engineering team.
What is the purpose of user acceptance testing? To confirm that the software satisfies the business needs and agreed criteria before release or payment.
What are the key steps in user acceptance testing? Define criteria, prepare journeys and data, execute realistic flows, record results, triage issues, retest fixes, and sign off only when the acceptance bar is met.
What tools are used for user acceptance testing? Often spreadsheets, shared docs, tickets, screenshots, and video captures are enough for a non-technical acceptor. Tooling is secondary to clarity. If a team is selling you a tool before they give you a good process, they are solving the wrong problem.
What is a user acceptance testing checklist? It is the short, reusable list of criteria, journeys, data, permissions, evidence, and sign-off conditions you use every release. The checklist above is the practical version.
Close: what you are actually signing
When you sign off software, you are not blessing the code. You are accepting a business outcome under known conditions. That is why the process has to be explicit, criterion-led, and divided into the three gates that matter: engineering QA, founder acceptance, and production readiness.
A good demo can hide a lot. A proper acceptance process reveals only what needs to be revealed: whether the product truly does the job, and whether the team can prove the rest is safe to release.