Black, White and Grey Box
The three ways to look at software when you test it (from the outside, from the code, or with a peek inside) plus experience-based testing, and when a manual tester uses each.
Picture a coffee machine in an office. Anyone can test it: put in a cup, press Cappuccino, taste the result. The service technician tests it differently: they open the maintenance panel and read the water temperature and the error log. And the engineer who designed it can open the case and look at every pipe and circuit.
Same machine, three levels of “seeing inside”. Software testing has exactly the same three views, and they have names: black box, grey box and white box.
The three boxes in one picture
Black box
You see inputs and outputs only. Tests come from requirements and user expectations.
Typical: manual testers, UAT
Grey box
You test from the outside, but use some inside knowledge: API calls, the database, logs, the architecture.
Typical: modern manual testers
White box
You see the code itself and design tests so every line and branch runs.
Typical: developers, unit tests
The quick version
Black box: test what the user sees
Black-box testingBlack-box testingTesting based only on inputs and outputs, without looking at the code.Open in glossary → treats the app as a sealed box. You put something in (tap, type, swipe) and check what comes out, compared with the requirementsRequirementA statement of what the software must do or how well it must do it.Open in glossary →. You don’t need to know how it works inside. Most manual testing is black box.
Black-box testers use structured techniques to choose good inputs: equivalence partitioning, boundary value analysis, decision tables and state transition testing.
White box: test the code’s structure
White-box testingWhite-box testingTesting based on knowledge of the internal code and logic.Open in glossary → designs tests by reading the code. The goal is coverageTest coverageHow much of the product, requirements or risks your tests actually check.Open in glossary →: making sure every line (statement coverage) and every “yes/no” path of each if (branch coverage) has been run by at least one test. Developers usually do this with unit testsUnit testingTesting the smallest pieces of code, like a single function, usually by developers.Open in glossary →.
Grey box: outside testing with inside knowledge
Grey-box testingGrey-box testingTesting from the outside with some knowledge of the inside, like the database or API.Open in glossary → is the middle ground: you still test through the UI, but you also look at the API calls in DevToolsDevToolsDeveloper tools built into browsers for inspecting pages, network traffic and errors.Open in glossary →, check the database, read logs, or use what you know about the architecture. It lets you find bugs the screen hides and write much sharper bug reports. It’s a big part of a modern manual tester’s job.
Plus: experience-based testing
The fourth family isn’t about the box at all. Experience-based techniques use the tester’s knowledge and intuition: guessing likely errors (names with apostrophes, double taps on Pay), exploratory testingExploratory testingLearning, designing and running tests at the same time, guided by curiosity and a goal.Open in glossary →, and working through checklistsChecklistA simple list of things to check, lighter and faster to use than full test cases.Open in glossary →.
Black-box testing: from the outside
Black-box testingBlack-box testingTesting based only on inputs and outputs, without looking at the code.Open in glossary → means testing the app without looking at how it’s built. You know what goes in and what should come out; what happens in between is a closed box.
Where black-box tests come from
Your “source of truth” is everything that describes how the app should behave:
- RequirementsRequirementA statement of what the software must do or how well it must do it.Open in glossary →, user storiesUser storyA short description of a feature from the user's point of view.Open in glossary → and acceptance criteriaAcceptance criteriaConditions a user story must meet to be considered done and accepted.Open in glossary →
- Designs and prototypes (Figma screens, flows)
- Platform conventions (what an iOS or Android user expects, like the back gesture)
- Common sense and the user’s point of view, especially when the spec is silent
Black-box techniques
Because you can’t test every input, black-box testing has a toolbox of techniques for picking the inputs most likely to find bugs. Each has its own lesson:
| Technique | Core idea | Example |
|---|---|---|
| Equivalence partitioning | Group inputs that behave the same, test one from each group | Age 25 stands for every adult age |
| Boundary value analysis | Bugs gather at the edges | Test €49.99, €50.00 for a “€50 or more” rule |
| Decision tables | Test every combination of conditions | Member? × order ≥ €30? × rainy day? |
| State transition | Test moves between states | Order: placed → paid → shipped → delivered |
| Use case testing | Follow a full user journey, plus its alternatives | Search → add to cart → pay → receipt |
Use case testing means walking through a complete scenario the way a real user would (the “happy path”), then each alternative and error path: card declined, address missing, app sent to the background mid-payment. It’s how most end-to-end test scenariosTest scenarioA high-level idea of what to test, such as 'User resets a forgotten password'.Open in glossary → in feature lessons are built.
Strengths and limits
Black-box testing finds what users will actually run into: wrong totals, confusing messages, broken flows, missing features. It needs no programming skills, and it catches missing behavior: if the requirement says “send a receipt by email” and the code never does, only a test based on the requirement will notice.
Its blind spot: code paths that no requirement mentions. If a developer left a secret “STAFF50” discount code in the app, no requirement-based test will ever try it. That’s where the other boxes help.
White-box testing: from the code
White-box testingWhite-box testingTesting based on knowledge of the internal code and logic.Open in glossary → designs tests from the internal structure of the code. The tester (usually the developer) reads the code and chooses inputs that make specific lines and paths run.
Statement and branch coverage, simply
CoverageTest coverageHow much of the product, requirements or risks your tests actually check.Open in glossary → measures how much of the code your tests actually executed. The two kinds every tester should understand:
- Statement coverage: the percentage of code lines (statements) that ran at least once.
- Branch coverage: every decision (
if) has two exits, true and false. Branch coverage is the percentage of those exits your tests went through.
Here is a tiny piece of pseudo-code for a gym app’s late-cancellation fee:
1 if hoursBeforeClass < 12:
2 fee = 5
3 show "Cancellation fee: €" + fee- One test: cancel 2 hours before. The
ifon line 1 is true, so lines 1, 2 and 3 all run. That’s 100% statement coverage, because every line ran. But only the true exit of theifwas taken: 50% branch coverage. - Add a second test: cancel 24 hours before. Now the
ifis false and line 2 is skipped. Together, the two tests took both exits: 100% branch coverage. - Why it matters. Look at what the second test shows: “Cancellation fee: €undefined”, because
feeis never set on the false path. Test 1 alone had 100% statement coverage and completely missed this bug. Only the branch-coverage test found it. Branch coverage is stronger than statement coverage; 100% branch coverage always gives 100% statement coverage, but not the other way around.
Who does white-box testing?
Mostly developers, through unit testsUnit testingTesting the smallest pieces of code, like a single function, usually by developers.Open in glossary → and code reviews, and coverage tools in the build pipeline report the percentages. As a manual tester you’ll rarely write white-box tests, but white-box thinking still helps you:
- Reading a pull request description or diff can show you a new
iffor “country == UK” that deserves a test. - Asking a developer “which paths aren’t covered by unit tests?” points you at risky areas.
- Knowing that a coverage report exists means you can ask for it when deciding where to focus.
Grey-box testing: outside, with a peek inside
Grey-box testingGrey-box testingTesting from the outside with some knowledge of the inside, like the database or API.Open in glossary → mixes the two. You still test through the user interface, like a user, but you use partial knowledge of the inside to choose better tests and to check results the screen doesn’t show.
What “inside knowledge” looks like in practice
| What you look at | Tool | What it reveals |
|---|---|---|
| API requests and responses | DevTools, Postman | The real data sent and received, status codesHTTP status codeA three-digit number in every server response: 200 means OK, 404 not found, 500 server error.Open in glossary →, hidden errors |
| Mobile app traffic | Proxy tools (Charles, Proxyman) | The same, for iOS and Android apps |
| The database | SQL client, admin panel | Whether the order, refund or status was really saved |
| Logs | DevTools Console, logcatLogcatAndroid's system log, read with adb logcat, where apps write errors and crash details.Open in glossary →, Xcode console, server logs | Errors and warnings behind a vague UI message |
| The architecture | Talking to developers, diagrams | Caches, background jobs, third-party services: where things can break |
A grey-box bug story
A tester on a travel app books a hotel. The screen says “Booking confirmed!”, which looks perfect from a black-box view. But in the Network panel they see the confirmation call returned 202 Accepted and a second call, POST /api/payments, failed with 500. A quick look in the test database confirms it: booking saved, payment status FAILED. The customer would have arrived at a hotel with no payment.
Without grey-box knowledge, that bug report would say “seems fine”. With it, the report names the failing endpointEndpointA specific API address the app calls, like GET /api/products or POST /api/login.Open in glossary →, includes the response body, and the developer fixes it in an hour. See writing bug reports for how to attach this evidence.
Experience-based techniques: the fourth family
Not every good test comes from a document or from code. Experience-based techniques use the tester’s knowledge of where software usually breaks. ISTQB groups three of them:
- Error guessing. Predicting mistakes developers commonly make and testing for them: a surname like O’Brien or Nguyễn, an empty search, a double tap on Pay (see double submitDouble submitA bug where an action runs twice because the user tapped or clicked twice quickly.Open in glossary →), a date like 29 February, a negative quantity in the cart.
- Exploratory testingExploratory testingLearning, designing and running tests at the same time, guided by curiosity and a goal.Open in glossary →. Learning, designing and running tests at the same time, guided by curiosity and a time-boxed goal (“30 minutes: try to break the new chat”). It’s not random clicking: good explorers take notes and follow interesting clues.
- Checklist-based testing. Working through a list of things to check, built from experience, like the checklists at the end of each component page. Lighter than full test cases, and great for regression.
These work best on top of structured techniques: the structured ones make sure you cover the requirements, the experience-based ones catch what nobody wrote down.
Comparing the approaches
| Based on | Who usually | Finds best | |
|---|---|---|---|
| Black box | Requirements, user view | Testers, users (UAT) | Wrong or missing behavior |
| White box | Code structure | Developers | Untested code paths, logic slips |
| Grey box | Partial inside knowledge | Testers, often with dev help | Hidden failures, data and API bugs |
| Experience-based | Tester’s knowledge | Experienced testers | Unexpected, “nobody thought of that” bugs |
How they work together on one feature
Let’s say a food delivery app adds a promo code field at checkout.
- Black box first. From the requirement “SAVE10 gives 10% off orders of €50 or more”, test €49.99 and €50.00, an invalid code, an expired code, lower-case “save10”.
- Grey box alongside. With DevTools or a proxy open, check the request sends the code, the response returns the right discount, and the order row in the database stores the discounted total, not the original.
- White box from the developers. Unit tests cover each branch of the discount function; the coverage report shows one uncovered branch for “STAFF50”, which leads to a conversation: should that code even be live?
- Experience-based to finish. Paste a code with a trailing space, apply two codes quickly, apply a code then empty the cart, switch apps mid-checkout.
Common misconceptions
- “Black box is the beginner’s version.” No. Designing strong black-box tests is a real skill, and it’s the only approach that catches missing features.
- “White box means 100% coverage, so we’re done.” Coverage shows what ran, not what’s correct or missing.
- “Grey box needs programming.” Reading a network request or running a simple database query is a learnable skill that needs no coding.
- “Exploratory testing is random clicking.” Good exploratory testing has a goal, a time box and notes.
Try it: see inside the box
Below is one small checkout feature from a pizza delivery app. Switch between the three views and run some tests. In white box mode, try to reach 100% branch coverage with as few tests as you can, and look carefully at what the code does that the requirements never mention.
See inside the box
One feature, three views. Run a few tests in each mode and notice what extra information you get as the box becomes transparent.
You see only what a customer sees: the screen, your inputs and the result. Your tests come from the requirements.
Requirements (all you get in black box)
- Delivery costs €2.99.
SAVE10gives 10% off orders of €50 or more.FREESHIPmakes delivery free.- Members always get free delivery.
- Unknown codes show an error.
Checkout · PizzaGo
Run a test to see the result.
The inside is hidden
You know the inputs (subtotal, code, member) and the output (the total or an error). Is the error message helpful? Is €50 exactly accepted? You can only find out by trying.
Which approach is this?
Which approach is this?
Pick the best fit for each test. You get instant feedback.
1.Using only the spec, you try order totals of €49.99, €50.00 and €50.01 to see exactly where the SAVE10 code starts working.
2.After tapping Pay, you open the Network tab in DevTools and check that the request sends the amount in cents (4999) and not as 49.99.
3.A developer writes unit tests so that both the “if” and the “else” of the late-payment fee rule run at least once.
4.Without a script, you spend 45 minutes on the new in-app chat: emojis, a 5,000-character message, airplane mode mid-send, rotating the phone.
5.From the requirements, you list every combination of “member?”, “order ≥ €30?” and “rainy day?” and test each one.
6.Because apps often trip over apostrophes, you sign up as “Seán O’Brien” and check the name on the receipt.
7.You cancel an order in the app, then query the test database to confirm the order’s status changed to CANCELED and the refund row was created.
8.Reading a pull request, you notice a new branch for “country == UK” that none of the existing tests execute, and design an input for it.
9.Knowing the product list is cached for 5 minutes, you change a price in the admin panel and time how long the old price stays visible in the app.
Practice: four views of a password reset
Here is a small spec for a banking app:
“On the login screen, Forgot password? asks for an email. If the email belongs to an account, we send a reset link valid for 30 minutes. For security, the screen always shows: If an account exists, we’ve sent you an email.”
Write down one test idea for each approach: black box, grey box, white box and experience-based. Then compare with the examples below.
Show example answers
Black box: Request a reset for a registered email, wait 31 minutes, open the link: it must say the link has expired.
Grey box: Request a reset for an unregistered email and check in DevTools that the API response is identical to the registered case (same status code, same body). Otherwise attackers can find out who has an account.
White box: A developer’s unit tests cover both branches of “account exists?” and both branches of “link older than 30 minutes?”.
Experience-based: Request two resets in a row and try the first link (should old links still work?), or enter the email with capital letters and a trailing space.
Check your understanding
Quick quiz
0/6 answered · 0 correct
1.A tester checks a sign-up form only against the acceptance criteria, without knowing anything about the code. Which approach is this?
2.One test runs every line of a function, but each `if` only ever went the 'true' way. What do you know?
3.Your app shows 'Payment successful', and you open DevTools to confirm the payment API really returned 200 and the order saved. Which approach is that?
4.Why can't 100% code coverage guarantee the app is correct?
5.You type a surname with an apostrophe because you know many apps break on it. Which technique is this?
6.Which bug is black-box testing best at finding?
Key takeaways
- Black box tests behavior from the outside, based on requirements. It’s what manual testers do most, using techniques like equivalence partitioning, boundaries, decision tables and state transitions.
- White box designs tests from the code. Statement coverage counts lines run; branch coverage counts true/false exits taken and is the stronger measure.
- 100% coverage shows what ran, not what’s right or what’s missing.
- Grey box is outside testing with inside knowledge (API responses, the database, logs, architecture), and it’s a core skill for modern manual testers.
- Experience-based techniques (error guessing, exploratory testing, checklists) catch what no document mentions.
- Strong testing combines all four on the same feature.
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 ⚡