Skip to content
Bugwise
Menu
Tutorials

Testing Without Documentation

No spec, no user stories, no acceptance criteria? Learn where to find the truth anyway, how to decide what counts as a bug using oracles and consistency heuristics, how to map an unknown app, confirm assumptions and prioritize by risk, with a worked example on an undocumented loyalty points feature.

intermediate Mobile & web
Short on time? Switch to the quick version.

It’s Tuesday morning at a coffee chain’s app team. Your lead drops by:

“We’re releasing the new Loyalty points in the Brewly app on Friday. Can you test it? There’s no spec. The product manager who designed it left last month, and the developers built it from a few Slack threads and a Figma file.”

You open the ticket. It says: “Loyalty points v1.” That’s it. No user storyUser storyA short description of a feature from the user's point of view.Open in glossary →, no acceptance criteriaAcceptance criteriaConditions a user story must meet to be considered done and accepted.Open in glossary →, no test casesTest caseA written set of steps, data and an expected result used to check one specific behavior.Open in glossary →.

Welcome to real life. Many testers spend a big part of their career testing things nobody wrote down. The good news: “no documentation” almost never means “no information”. The information is just scattered across the app, the company and people’s heads. This tutorial shows you how to collect it, how to decide what’s a bug without a spec to point at, and how to leave a little documentation behind so the next person has it easier.

Why there’s so often no spec

  • Startups move fast with tiny teams. The founder knows how it should work; nobody has time to write it down.
  • Legacy apps were built years ago. The documents (if they existed) are outdated, lost in an old wiki, or describe a version that no longer exists. The people who wrote them have left.
  • Fast-moving teams ship small changes every day. The “spec” is a two-line ticket, a Slack thread and a quick chat at someone’s desk.
  • Hidden behavior. Even with a spec, a lot of behavior is never described: what happens on a refund, on a slow network, after an app update. You’ll meet undocumented behavior in every project.

The essentials

Where to find the “truth”

When there’s no requirementRequirementA statement of what the software must do or how well it must do it.Open in glossary →, look for anything that tells you how the product should behave:

SourceWhat it tells you
The app itselfHow it behaves now, and whether it’s consistent with itself
Competitors and platform conventionsWhat users already expect from similar apps, on iOS, Android and the web
App store listing, marketing pagesPromises the company has made publicly
Support tickets and reviewsWhat confuses or angers real users today
AnalyticsWhich features and flows people actually use
Designs (Figma)What the designer intended, including states
API docs (Swagger/OpenAPIOpenAPIA standard file format that describes an API's endpoints, parameters and responses (formerly called Swagger).Open in glossary →)Fields, rules and limits the backend enforces
Code, commits, PR descriptionsWhat the developer meant to build, and when it changed
PeopleDevelopers, product owner, support, sales: ask them
Previous bug reportsKnown weak spots and past decisions

Oracles: how to decide what’s a bug

An oracle is any way of telling whether a result is right or wrong. Without a spec, you compare the product with other things. Testers Michael Bolton and James Bach summed these up in a well-known heuristic called HICCUPPS. The simple version: a behavior is suspicious when it’s inconsistent with:

  • the product itself (Home says 112 points, Rewards says 120)
  • comparable products (every other coffee app takes points back on a refund)
  • user expectations (a refund should never add points)
  • claims the company made (the store listing says “free drink of any size”)
  • standards and guidelines (touch targets of at least 44×44 pt on iOS)
  • history (the previous version did it differently, and nobody asked for a change)

The method in six steps

  1. Collect sources. Spend 30 minutes finding the listing, designs, API docs, tickets and the right people.
  2. Explore and map. Use the app with a goal and draw a feature map as you go.
  3. Write down assumptions. “I assume a refund removes the points.” Get each one confirmed by someone who can decide.
  4. Prioritize by risk. Test money, data and core flows first.
  5. Judge with oracles. For every odd behavior, name the oracle that says it’s wrong.
  6. Leave documentation behind. A checklist, the feature map and a small glossary of the app.

Reporting a bug without a spec

The “Expected” line of a bug reportBug reportA clear written description of a bug so developers can reproduce and fix it.Open in glossary → still needs a reason. Say which oracle you used:

Names the oracle

Expected (App Store listing claim): 100 points buy a free drink of any size, as the listing says. Actual: the reward only allows a small drink.

Just an opinion

Expected: it should work properly. Actual: only small drinks, which is wrong.

When no oracle settles it, don’t file a bug: ask a question and log it as an assumption to confirm.

Switch to Detailed at the top of the page for the full method: every source and how to use it, the HICCUPPS heuristics with examples, feature maps, assumption logs, lightweight documentation templates, risk-based prioritization and a full worked example.

Where to find the “truth”

Think of yourself as a detective arriving at a scene with no witness statement. There are still clues everywhere; you just have to know where to look. Spend your first 30 to 60 minutes collecting them before you test in depth. It pays back all week.

The product itself

The app is the most honest document you have: it shows exactly what was built. Use it to learn the vocabulary, the screens and the flows, and to find internal contradictions (two screens that disagree, one button that behaves differently in two places). Check every platform you have: the iOS app, the Android app and the website often disagree with each other, and each disagreement is a clue.

Outside the company

Inside the company

People

Developers, the product owner (PO), designers, support agents and sales people each hold part of the picture. Sales and support know what customers were promised; developers know what was built; the PO decides what should happen.

Oracles: deciding what’s a bug

An oracle is anything that helps you decide whether a result is right or wrong. A spec is one oracle, and a very convenient one. But there are many others, and experienced testers use several at once.

The consistency heuristics (HICCUPPS)

Michael Bolton and James Bach, two well-known testing teachers, collected these oracles into a memorable heuristic called HICCUPPS. Each letter is a kind of consistency. A behavior that’s inconsistent with one of them is a candidate problem.

Consistent with…Ask yourselfBrewly example
HistoryDid it work differently before?Last version showed the expiry date; now it doesn’t
ImageDoes it fit the brand the company wants?A “premium” brand shows “ERR_NULL” in a popup
Comparable productsHow do similar apps do it?Other loyalty apps reverse points on refunds
ClaimsDoes it match what was promised?Listing: “free drink of any size”, app: “small only”
User expectationsWhat would a reasonable user expect?Canceling an order shouldn’t add points
ProductIs it consistent with itself?Home shows 112 points, Rewards shows 120
PurposeDoes it serve what the feature is for?Redeem is hidden two screens deep in Settings
Statutes and standardsDoes it follow laws and guidelines?Redeem link is 20 pt tall (iOS asks for 44×44 pt)

You don’t have to memorize the acronym. What matters is the habit: for every odd behavior, ask “inconsistent with what?” If you can answer, you have a reason. If you can’t, you probably have a question, not a bug.

Build a feature map while you explore

A feature map (or mind map) is a tree of everything the product does: areas, features, and the details inside them. Start with the app name in the middle, add the main areas (Rewards, Ordering, Payments, Account, Notifications) and keep adding branches as you discover things.

Why it’s worth the effort:

Use a whiteboard, a mind map tool (XMind, Miro, FigJam) or a simple indented list. You’ll build one for Brewly in the practice section below.

Explore in focused sessions of 60 to 90 minutes, each with a short goal written down first, a test charterTest charterThe goal and scope of an exploratory testing session, written before it starts.Open in glossary →: “Explore earning and refunding points with card and gift card payments, to find out how the balance changes.” Exploratory Testing covers charters and sessions in depth.

Write down assumptions and get them confirmed

Without a spec, you’ll constantly make assumptions: “points are probably awarded when you pay”, “a refund probably removes them”. That’s fine, as long as you write them down and get them confirmed by someone who can decide (usually the product owner). Unwritten assumptions turn into silent gaps in your testing.

A simple assumption log:

#AssumptionBased onStatus
A1Points are awarded when the order is paidPR descriptionConfirmed by dev
A2$4.50 earns 4 points (round down)Listing: “1 point per $1”Asked PO
A3A refund removes the earned pointsUser expectationConfirmed by PO
A4Tips don’t earn pointsGuessOpen

Specific, easy to answer

“The listing says 1 point per $1. A $4.50 latte earned 5 points. Should it be 4 (round down) or 5 (round to nearest)?”

Vague, gets ignored

“Can you explain how the points calculation is supposed to work?”

Create lightweight documentation as you go

You’re not expected to write the missing 40-page spec. But leaving small, useful artifacts behind is one of the most valuable things a tester can do on an undocumented product:

A template you can copy into your team’s wiki:

Feature: Loyalty points (Brewly)        Last updated: 14 Oct, by Sam (QA)

What it does (in one sentence):
  Customers earn points on paid orders and swap 100 points for a free drink.

Sources:  App Store listing, Figma "Rewards v3", Swagger /loyalty, PR #812

Glossary: bean = 1 loyalty point · reward = free drink · tier = Silver/Gold

Confirmed rules:
  - Points awarded when the order is paid (dev, PR #812)
  - Refund removes the points earned by that order (PO, 12 Oct)

Open questions:
  - Do tips earn points?

Checklist: earn · balance on all screens · redeem · refund · expiry · offline

Prioritize by risk

You’ll never test everything, especially when you’re still discovering what “everything” is. So test the riskiest things first. Risk is roughly impact × likelihood (the same idea as the risk scores in Writing a Test Plan):

  • Impact: what happens if this breaks? Money, personal data, legal problems and core flows (sign in, pay, order) are high impact.
  • Likelihood: how likely is it to break? New code, complex rules (rounding, time zones), many integrations, and areas with past bugs are more likely to fail.
RiskTypical examplesWhen to test
HighEarning and redeeming points, refunds, payments, balance shown to usersFirst, deeply
MediumExpiry, tiers, store selection, notificationsNext
LowProfile settings, activity history layout, promo bannersIf time allows

Support tickets and analytics are excellent inputs here: a feature that gets many complaints or a lot of traffic deserves more attention. When you report what you found, you’ll also suggest severitySeverityHow much damage a bug does to the product or the user.Open in glossary →; see Severity vs Priority for how that differs from the team’s fixing priorityPriorityHow soon a bug should be fixed, based on business needs.Open in glossary →.

Reporting bugs when there’s no spec

Everything you learned in How to Write a Bug Report still applies. The one difference is the Expected result: you can’t write “as per requirement REQ-12”. Instead, name the oracle in brackets and, if possible, link or quote it.

Expected, with its oracle

  • Expected (consistency with the Home tab): the Rewards tab shows the same balance as Home, 112 points.
  • Expected (iOS Human Interface Guidelines): the Redeem control is at least 44×44 pt.
  • Expected (confirmed by PO in SHOP-311): a refund removes the points the order earned.

Expected, without a reason

  • Expected: correct balance.
  • Expected: bigger button.
  • Expected: refund should work properly.

A few more tips:

  • Separate facts from judgment. The actual result is a fact. The expected result is your judgment, backed by an oracle. Readers can then disagree with the oracle without doubting your observation.
  • Use “inconsistent with” language when two sources disagree: “The app allows small drinks only, which is inconsistent with the App Store listing (‘any size’). One of them needs to change.”
  • Don’t file opinions as bugs. If no oracle supports it, raise it as a question or an improvement suggestion.
  • Expect “works as designed”. Sometimes the team decides the odd behavior is intended. That’s a good outcome too: you now have a confirmed rule to add to your documentation.

The method, step by step

  1. Clarify the mission. Ask your lead what matters most: “Is the goal to find release blockers by Friday, or to learn the whole feature?” and how much time you have.
  2. Collect sources (30 to 60 minutes). Store listing, marketing page, Figma, Swagger, recent PRs, support tickets, old bugs. Note who knows what.
  3. Do a first tour. Use the feature like a customer would, end to end, on one device. Don’t hunt for bugs yet; learn the words and the flows.
  4. Draw the feature map. Areas, features, details. Mark what you don’t understand with a question mark.
  5. Log assumptions and ask. Turn every question mark into a specific, written question for the right person.
  6. Rate risk and plan sessions. Pick the high-risk features and write a charter for each session.
  7. Explore with oracles. For each odd behavior, ask “inconsistent with what?” Report bugs with the oracle named; log questions instead of guesses.
  8. Leave documentation behind. Update the feature map, checklist, glossary and confirmed rules. Turn confirmed rules into test cases for next time.

Worked example: Brewly’s undocumented Loyalty points

Back to Tuesday morning. Here’s how an experienced tester tackles the Friday release.

Tuesday, 9:00: collecting sources

SourceWhat it revealed
App Store listing“Earn 1 bean for every $1. 100 beans = a free drink of any size.” (Beans are Brewly’s points.)
Figma “Rewards v3”Rewards tab, a points card on Home, an expiry banner, Silver/Gold tiers
SwaggerGET /loyalty/balance, POST /orders/{id}/refund, an expiresAt field on each points entry
PR #812“Award points when the order is paid (not at pickup)”
Support ticketsTwo complaints from the beta: “points vanished after canceling”
Developer chatiOS and Android teams built the screens separately

Already a lot: a public promise, intended screens, an expiry rule nobody mentioned, the moment points are awarded, a known weak spot (cancellations) and a hint that the two platforms may differ.

Tuesday, 10:30: first tour and feature map

The tester orders a flat white on iOS, checks the Rewards tab, refunds the order from the order history, then repeats everything on Android. The feature map grows: Rewards → Earning, Balance, Redeeming, Refunds, Expiry, History, plus Ordering, Payments and Account around it.

Tuesday, 11:30: assumptions and questions

The tester posts four questions in the team channel and the ticket:

  1. “Should $4.50 earn 4 points (round down, as ‘1 per $1’ suggests) or 5?” → PO: round down.
  2. “Should a refund remove the points the order earned?” → PO: yes.
  3. “Do gift card payments earn points?” → PO: yes, any payment.
  4. “Do tips earn points?” → PO: not decided. Becomes a new user story, out of scope for Friday.

Tuesday afternoon to Wednesday: exploring by risk

High-risk features first: earning, balance, refunds, redeeming. What the tester found:

#FindingOracleSeverity
1Refunding an order adds points instead of removing themConfirmed by PO (question 2), user expectationCritical
2$4.50 earns 5 pointsConfirmed by PO: round downMajor
3Gift card payments earn 0 pointsClaim (“every $1”), confirmed by POMajor
4Android calls them “Points”, iOS “Beans”Consistency within the productMinor

Finding 1 is critical because customers could order, refund and repeat to collect free drinks: real money for the business. Finding 4 surfaced only because the tester was writing the app’s glossary.

Wednesday: the bug report

Here’s how finding 3 looks as a report. Note how the expected result names its oracles.

Title:        Rewards: Paying with a gift card earns 0 points (card payments earn points)
Environment:  Brewly 3.2.0 (build 410), iPhone 15, iOS 18.0.1, Staging
Preconditions: Signed in as test user sam.qa; gift card balance $20; 40 points
Steps:
  1. Add a Flat white ($4.20) to the cart
  2. Tap Checkout and choose "Gift card"
  3. Tap Pay, then open the Rewards tab
Expected (App Store claim "Earn 1 bean for every $1", confirmed by PO in SHOP-318):
  Balance increases by 4 points, to 44.
Actual:
  Balance stays at 40. No activity entry is added. Same order paid by card earns 4 points.
Reproducibility: 3/3 attempts
Attachments:  gift-card-no-points.mp4

Thursday: leaving documentation behind

Confirmed rules from the PO turn into proper test cases (see How to Write Test Cases) for every future release:

TC-LP-01Paid order earns 1 point per whole dollar, rounded down

Preconditions

  • Signed in as a test user with 40 points
  • Rule confirmed by PO in SHOP-318

Steps

  1. Order a Latte ($4.50) and pay by card
  2. Open the Rewards tab

Test data

Latte $4.50

Expected result

Balance shows 44 points (+4). Activity shows 'Latte · $4.50 · +4'. Home shows the same 44 points.

TC-LP-02Refund removes the points the order earned

Preconditions

  • Signed in with 44 points after the order in TC-LP-01

Steps

  1. Open Order history
  2. Refund the Latte order
  3. Open the Rewards tab

Expected result

Balance returns to 40 points. Activity shows 'Refund · Latte · −4'.

TC-LP-03Gift card payment earns points like a card payment

Preconditions

  • Signed in with 40 points
  • Gift card balance at least $5

Steps

  1. Order a Flat white ($4.20)
  2. Pay with the gift card
  3. Open the Rewards tab

Expected result

Balance shows 44 points (+4), the same as a card payment.

TC-LP-04Balance is identical on Home and Rewards after an order

Preconditions

  • Signed in with 40 points

Steps

  1. Place and pay an order
  2. Check the points card on Home
  3. Open the Rewards tab
  4. Repeat on the Android app

Expected result

The same balance, and the same word for points, appears on both screens and both platforms.

Tip: click a test case to expand it.

The feature map, assumption log, glossary and these test cases go onto one wiki page. On Friday, the next tester to touch loyalty points starts with documentation that didn’t exist on Tuesday.

Common mistakes

MistakeWhy it hurtsInstead
Refusing to test until there’s a specThe release goes out anyway, untestedCollect sources and start exploring
Filing opinions as bugsDevelopers stop trusting your reportsName an oracle, or ask a question
Keeping assumptions in your headGaps nobody knows aboutLog them and get them confirmed
Treating the app as always rightYou only confirm what was builtCompare it with claims, users, rivals
Treating one oracle as the truthOutdated pages mislead youReport inconsistencies, let the PO decide
Testing in random orderCritical bugs found on Friday eveningMap features, rate risk, start high
Leaving nothing behindThe next tester starts from zeroFeature map, checklist, glossary

Practice 1: Oracle detective

Here’s a tiny version of Brewly’s Rewards feature, with no spec. You have only the app and its App Store listing. Explore both tabs, then judge each numbered observation: is it a bug, not a bug, or a question to confirm first? And which oracle backs your decision?

Oracle detective

Brewly's new Rewards feature has no spec. Explore both tabs, tap the numbered markers, and decide for each observation: is it a bug, and which oracle tells you so?

9:41

Good morning,

Sam

Brewly Rewards

112 beans

A free drink is waiting for you

Order again

  • Flat white$4.20
  • Latte$4.50
  • Blueberry muffin$3.10

Tip: open the Rewards tab to see your beans.

App Store listing (excerpt)

Brewly: Order ahead & earn

Skip the line and earn as you sip. Earn 1 bean for every $1 you spend. 100 beans = a free drink of any size.

0 of 7 checked

0 fully right

  • The Home tab says you have 112 beans. The Rewards tab says 120 beans. Same account, seconds apart.

    Your verdict
    Which oracle justifies it?

Practice 2: Map the app

Build a feature map of Brewly. Open each area to “explore” it, rate the risk of each feature you find, and add features you’d expect but don’t see listed (offline mode? tiers? store hours?). Then compare your ratings with an experienced tester’s and turn the map into notes.

Feature map builder

Explore the Brewly app one area at a time. Rate the risk of each feature you find, add anything else you would expect to see, then compare with an experienced tester.

Brewly app

Before you test something undocumented

Testing without documentation

0 of 10 checked

Check your understanding

Quick quiz

0/6 answered · 0 correct

  1. 1.In testing, what is an oracle?

  2. 2.The Home screen shows 112 points and the Rewards screen shows 120. Which oracle tells you this is a bug?

  3. 3.The app store listing promises a free drink of any size, but the app only allows a small one. What should you do?

  4. 4.A $4.50 purchase earns 5 points, and the listing says '1 point for every $1'. No one has defined rounding. What's the best next step?

  5. 5.You have two days and an undocumented feature. What do you test first?

  6. 6.Which 'Expected' line is best for a bug report without a spec?

Key takeaways

  • No documentation rarely means no information. The truth is spread across the app, store listings, designs, API docs, PRs, support tickets, old bugs and people.
  • An oracle is any way to decide if a result is right. Look for inconsistency with the product itself, comparable products, user expectations, claims, standards, history (the HICCUPPS heuristic).
  • Oracles are fallible. When sources disagree, report the inconsistency and let the product owner decide.
  • Build a feature map while you explore, and use it for coverage, risk and open questions.
  • Write assumptions down and get them confirmed in writing. No oracle? Ask a question instead of filing a bug.
  • Test by risk: money, data and core flows first.
  • In bug reports, name the oracle behind your expected result.
  • Leave lightweight documentation behind: checklist, feature map, app glossary, confirmed rules.

Finished this page?Nice work, this page is complete!

Mark it as done to track your progress. It's saved in this browser, no account needed.

Its review cards are now in Bites ⚡
Esc

Type to search the whole site.