Black·Box
DARK
SE401 · Software Quality Assurance and Testing · Chapter 02

You can't open the box,
so you interrogate the outputs.

Black-box testing throws away the source code and treats the system as a sealed unit: feed it inputs, watch the outputs, and derive test cases straight from the specification. Five systematic techniques — equivalence partitioning, boundary value analysis, decision tables, state transition testing, and use case testing — turn "try everything" into "try the few inputs that actually matter."

5 core techniques
Knight Capital: $460M in 45 min
Static vs. Dynamic map
Exam-tested
SYSTEM UNDER TEST BLACK BOX IN OUT EQ.PART BOUND DEC.TBL STATE USE CASE
§ 01 — BACKGROUND & PROCESS

From "what should we test?" to an executable test

Before you can pick a technique, you need to know what you're testing, what the inputs are, and what results should come out. That's the job of the three-stage test development process.

🎯
Memory hook
"Analyze, Design, Implement — in that order, every time."
Test analysis finds the test conditions → test design turns them into concrete test cases → test implementation organizes them into runnable test procedures.

1. Test Analysis

what to test

The test basis documentation is analyzed to identify the test conditions. A test condition is an item or event that could be verified by one or more test cases — a function, a transaction, a quality characteristic, or a structural element (e.g. a web page's menus).

"Throw a wide net!" First identify as many test conditions as possible, then select which to develop in detail. We can't test everything (P2 — the second testing principle), so we pick a subset with a high probability of finding defects — guided by a suitable test design technique.

2. Test Design

test cases + data

A test case is specified as a set of: Pre-conditions → Inputs → Expected results → Post-conditions, developed to cover certain test condition(s).

Test oracle: the source of truth for correct behavior. Expected results include outputs, changes to data/states, and any other consequence of the test. If expected results aren't defined up front, a plausible-but-wrong result can get mistaken for the correct one — so define them before execution.

3. Test Implementation

organize & schedule

Test cases are Developed → Implemented → Prioritized → Organized into test procedures. A manual test procedure specifies the sequence of actions for executing a test; an automated test procedure (test script) does the same for a test execution tool.

The execution schedule defines
  • The order of execution of test procedures / scripts
  • When they will be executed
  • By whom they will be executed
It accounts for
  • Risks, regression tests, prioritization
  • Technical and logical dependencies
Rule of thumb: "Find the scary stuff first." What counts as 'scary' depends on the business, system, and project risks.
§ 02 — CASE STUDY

Knight Capital: what happens when nobody tested the deployment

The motivating "why testing matters" story for this chapter — a real high-frequency-trading firm, one bad deployment, $460 million gone in 45 minutes.

🧟
Memory hook
"Zombie code doesn't die — it just waits to be reactivated."
Dead code left in a system is still a live risk. Testing (and deleting what you don't use) is how you make sure it stays dead.
Background

Knight Capital Group — largest U.S. equities trader

An American global financial services firm whose high-frequency trading (HFT) algorithms gave it a 17.3% market share on NYSE and 16.9% on NASDAQ.

Aug 1, 2012 — the first 45 minutes

Trading Program Ran Amok, With No 'Off' Switch

Knight's computers executed a series of unusually large automatic orders — "spit out duplicate buy and sell orders, jamming the market with high volumes of trades that caused wild swings in stock prices."

By end of day: $460 million loss. In two days, the company's market value plunged 75%.
What happened — "Zombie Software"

A dead function was inadvertently reactivated

A new algorithmic trading program was installed and began operation on Aug 1. A dormant legacy program was somehow "inadvertently reactivated," and once active it started multiplying stock trades by one thousand — sending 4 million orders when attempting to fill just 212 customer orders. Knight's staff looked through eight sets of software before determining what happened.

Nov 2012 — SEC investigation findings

Root causes traced back to 2005

  • Code changes in 2005 introduced defects. The defective function was not meant to be used — but it was kept in the codebase.
  • New code deployed in late July 2012 triggered the defective function under new rules; it was unable to recognize when orders had been filled.
  • Knight ignored system-generated warning emails.
  • Inadequate controls and procedures for code deployment and testing.
Oct 2013: charges filed — Knight Capital settled for $12 million.
Why this opens the chapter: every technique that follows exists to catch exactly this class of failure earlier — missing logic, unused-but-dangerous code paths, and inadequately tested deployments.
§ 03 — THE MAP

Static vs. Dynamic, and where black box fits

Before zooming into black-box techniques, place them on the full map of test design techniques.

Static vs. Dynamic testing

recall
Static testing

Manual examination and automated analysis of code without executing it — informal reviews, walkthroughs, technical reviews, inspections; plus static analysis (data flow, control flow).

Dynamic testing

Code is executed. Splits into three families: structure-based (white box — statement, decision, condition, multiple condition), specification-based (black box — this chapter), and experience-based (error guessing, exploratory testing).

🗂️
Memory hook — the three dynamic families
"See it, Spec it, Sense it."
See it = structure-based (you see the code: statement/decision/ condition coverage). Spec it = specification-based / black box (you read the spec, not the code — this chapter). Sense it = experience-based (you use tester intuition and experience).
📄

Static

Reviews & static analysis — no execution at all.

🏗️

Structure-based (white box)

Statement, decision, condition, multiple condition coverage.

Specification-based (black box)

Equivalence partitioning, boundary value, decision tables, state transition, use case — this chapter.

🧠

Experience-based

Error guessing, exploratory testing.

§ 04 — FUNDAMENTALS

What "black box" actually means

Also called functional testing or specification-based testing — three names for the same idea, each highlighting a different angle.

🔤
Memory hook — three names, one technique
"Functional (what it's derived from) = Specification-based (where it comes from) = Black-box (what you can't see)."
"Functional" refers to the source of information (the functional specification) — not to what is tested. It's not testing only "functions"; it's testing derived from a spec of intended behavior, formal or informal.

Black Box Testing

no view of the code

Testing software against a specification of its external behavior, without knowledge of internal implementation details. Applies to software "units" (e.g. classes) or to entire programs, using API docs / functional specs / requirements specs as the source of truth. Because it purposely disregards control structure, attention focuses on the information domain — data that goes in, data that comes out. Goal: derive sets of input conditions (test cases) that fully exercise the external functionality.

Black-box error categories
  • Incorrect or missing functions
  • Interface errors (usability problems, concurrency/timing errors)
  • Errors in data structures or external database access
  • Behavior or performance errors
  • Initialization and termination errors
Note: unlike white-box testing, black-box testing tends to be applied later in the development process.
Questions black-box testing answers
  • How is functional validity tested?
  • How are system behavior and performance tested?
  • What classes of input will make good test cases?
  • Is the system sensitive to certain input values?
  • How are the boundary values of a data class isolated?
  • What data rates/volume can the system tolerate?
  • What effect will specific combinations of data have?

The information domain

Inputs: individual input values (try many different values per input), combinations of inputs (inputs aren't independent — programs process several together), and the ordering & timing of inputs (which can also matter).

Defining the input domain: Boolean (T/F) · numeric value in a range (e.g. -99 ≤ N ≤ 99, integer/float, non-negative) · one of a fixed enumerated set ({Jan, Feb, Mar...}, {Visa, MasterCard, Discover...}) · formatted strings (phone numbers, file names, URLs, credit-card numbers, regex).

Why black box?

  • Early — can start before code is written; even incomplete/informal specs work (though precise, complete specs build better test suites). Side benefits: reveals ambiguities in the spec, assesses testability, and can even improve the spec itself (in the extreme, as in XP, test cases are the spec).
  • Effective — finds classes of defects like missing logic that structural (white-box) testing can never find, because it never focuses on code that isn't there.
  • Widely applicable — any description of behavior counts as a spec, at any granularity from module to system.
  • Economical — less expensive than structural testing. It's the base-line technique for designing test cases.

Functional vs. Structural: applicability

Functional (black box)Applicable at every granularity: unit test (module interface spec), integration test (API/subsystem spec), system test (system requirements spec), regression test (requirements + bug history).
Structural (white box)Applicable mainly to relatively small parts of a system — chiefly unit test.
Single Defect Assumption: failures are rarely the result of the simultaneous effects of two or more defects. This is why testing representative combinations — not every possible combination — is usually enough.

From specification to test cases — 4 steps

  1. Decompose the specification — if it's large, break it into independently testable features.
  2. Select representatives — representative values of each input, or representative behaviors of a model (often simple I/O transformations don't describe a whole system, so we use models in program spec, design, and test design).
  3. Form test specifications — typically combinations of input values, or model behaviors.
  4. Produce and execute actual tests.
Worked example — ZIP Code Lookup (input: 5-digit US postal code, output: list of cities): representative values include a correct zip code (with 0, 1, or many cities) and a malformed zip code (empty; 1–4 characters; 6 characters; very long; non-digit characters; non-character data). Notice how often boundary values (0 cities, 6 characters) and error cases show up — a preview of the next section.
§ 05 — TECHNIQUE 1

Equivalence Partitioning

The universe of possible test cases is too large to try them all — equivalence partitioning tells you which small subset to actually run.

🧩
Memory hook
"Same path, same test — pick one representative per group."
Two test cases are equivalent if you expect the program to process them the same way (follow the same path). If you expect that, only test one of them — that's the entire idea.

Equivalence Classes

divide & conquer the input domain

A black-box method that divides the input domain into classes of data from which test cases are derived. An ideal test case single-handedly uncovers a complete class of errors, reducing the total number of test cases needed. From each equivalence class, test cases are selected so the largest number of attributes of that class are exercised at once. Partitions should not share common elements — but don't worry if classes overlap with each other (better redundant than incomplete); they will, however, easily overlap with boundary-value test cases.

Guidelines for defining equivalence classes
Input condition specifies…Classes defined
A range (e.g. 1–10)1 valid + 2 invalid: {1..10}, {x<1}, {x>10}
A specific value (e.g. 250)1 valid + 2 invalid: {250}, {x<250}, {x>250}
A member of a set (e.g. {-2.5, 7.3, 8.4})1 valid + 1 invalid: {set}, {any other x}
A Boolean value1 valid + 1 invalid: {true}, {false}
Determining equivalence classes — checklist
  • Look for ranges of numbers or values
  • Look for memberships in groups
  • Some classes may be based on time
  • Include invalid inputs
  • Look for internal boundaries
  • Test multiple values per class — you're often unsure the classes were defined completely, so multiple values are more thorough than one
Different definitions of "equivalence" partition the same input space differently. E.g. int Add(n1, n2, n3, ...) could be partitioned by number of inputs, by sign of operands, or by magnitude — all valid, all different.

Worked example — integer & phone number

InputValid Equivalence ClassesInvalid Equivalence Classes
Integer N such that:
-99 ≤ N ≤ 99
[-99,-10], [-9,-1], 0, [1,9], [10,99] <-99, >99, malformed numbers (12-, 1-2-3), non-numeric strings (junk, 1E2, $13), empty value
Phone number
Area code: [200,999]
Prefix: (200,999]
Suffix: any 4 digits
555-5555, (555)555-5555, 555-555-5555, 200≤Area≤999, 200<Prefix≤999 Invalid formats (5555555, (555)(555)5555), area code <200 or >999, non-numeric characters in area code — similarly for prefix & suffix
Real-world groupings (technique in one line): inputs, outputs, and internal values are divided into groups expected to behave alike — e.g. People (woman/man), Students (bachelor/master), Tickets (children/youth/adults/older), Vehicles (gasoline/diesel/electric). Equivalence partitioning applies at all levels of testing and can be used to achieve both input and output coverage.
§ 06 — TECHNIQUE 2

Boundary Value Analysis

A greater number of errors occur at the boundaries of the input domain than in the "center" — so that's exactly where you aim.

🎯
Memory hook
"Kiss the edges, not just the middle."
Errors cluster near extreme values (off-by-one is the classic example). Boundary value analysis complements equivalence partitioning — it doesn't replace it — by selecting test cases right at the edges of each class.

Boundary Value Analysis

extension of equivalence partitioning

Selects test cases at the edges of a class, deriving them from both the input domain and the output domain. Use input values at their minimum, just above the minimum, at a nominal value, at the maximum, and just below the maximum. Robustness: how does the software react when boundaries are exceeded?

Guidelines
  1. If an input condition specifies a range bounded by a and b, design test cases at a and b, plus values just above and just below each.
  2. If an input condition specifies a number of values, exercise the minimum and maximum, plus values just above/below each.

Apply the same two guidelines to output conditions — produce output at the minimum, maximum, and just below/above each. If internal data structures have prescribed boundaries (e.g. an array), design a test to exercise them at their limits too.

The classic off-by-one bug
if (200 < areaCode && areaCode < 999) — Wrong!
if (200 <= areaCode && areaCode <= 999) — correct

Testing area codes 200 and 999 would catch this error; a center value like 770 would not. In addition to center values, always test values right on a boundary and very close to it on either side.

Worked example — same inputs as before

InputBoundary Cases
Integer N such that -99 ≤ N ≤ 99-100, -99, -98, -10, -9, -1, 0, 1, 9, 10, 98, 99, 100
Phone number — Area code [200,999], Prefix [200,999], Suffix 4 digitsArea code: 199, 200, 201 and 998, 999, 1000 — Prefix: 200, 199, 198 and 998, 999, 1000 — Suffix: 3 digits, 5 digits
Encoded-boundary example: numeric input is often typed as a string, then converted with something like int x = atoi(str);, which must distinguish digits from non-digits. A real boundary case: will the program wrongly accept / (ASCII 47, one below '0'=48) or : (ASCII 58, one above '9'=57) as digits?
Rule of thumb (closed, valid partitions): pick two boundary values (min and max), plus one value from the middle of the partition — and don't get so wrapped up in boundary cases that you neglect "normal" mainstream-usage input values users would actually type.

Limitations

  • Doesn't require much thought — easy to apply mechanically, easy to apply mindlessly
  • May miss internal boundaries
  • Usually assumes variables are independent
  • Values right at the boundary may not have meaning in every domain

Notes

  • Applies at all test levels
  • Relatively easy to apply, high defect-finding capability
  • Detailed specifications help a lot
  • Considered an extension of equivalence partitioning; boundary values are used for test data selection
§ 07 — TECHNIQUE 3

Decision Table Testing

When behavior depends on combinations of Boolean conditions, decision tables force you to consider every combination systematically — like a truth table for business rules.

📊
Memory hook
"Every column is a contract: these conditions, that action."
Recall truth tables from mathematical logic (P ∧ Q): each row/column is one combination of T/F inputs mapped to one output. Decision tables do the same for business rules.

Decision Table testing

a.k.a. cause-effect table

A good way to capture system requirements that contain logical conditions, to document internal system design, and to record complex business rules a system must implement. Useful whenever input conditions and actions can be stated as true/false (Boolean). The table contains the triggering conditions — all combinations of true/false for all input conditions — and the resulting actions for each combination. Its strength: it creates combinations of conditions that might not otherwise get exercised during testing, and it's effective at revealing faults hiding in the requirements themselves.

Coverage standard: at least one test per column — which typically means covering all combinations of triggering conditions. With n Boolean conditions you get up to 2ⁿ rules/columns, though many can be merged with "don't care" () dashes when a condition doesn't affect the outcome.

Worked example — credit card sign-up discount

Rules: new customers get 15% off; existing loyalty-card holders get 10% off; coupon holders get 20% off (but a coupon can't combine with the new-customer discount); discounts are added if applicable.

ConditionsR1R2R3R4R5R6R7R8
New customer (15%)TTTTFFFF
Loyalty card (10%)TTFFTTFF
Coupon (20%)TFTFTFTF
Discount×(invalid)×(invalid)20%15%30%10%20%0%
Simplified with "don't care" dashes: Rules 1&2 collapse to New=T, Loyalty=T, Coupon=— → invalid (new-customer discount can't combine with a loyalty card at all in this rule set), Rules 3&7 collapse to Coupon=T, New=— → 20%, leaving six effective rules instead of eight raw combinations — this consolidation is exactly what makes decision tables powerful for reasoning about business rules.
§ 08 — TECHNIQUE 4

State Transition Testing

For systems where the same input can produce different outputs depending on what happened before — the system's own history becomes part of the spec.

🔁
Memory hook — the four elements (STEA)
"State Transition Events Act."
States (what the software may occupy — open/closed, active/inactive) · Transitions (from one state to another — not all are allowed) · Events (cause a transition — closing a file, withdrawing money) · Actions (result from a transition — an error message).

State Transition Testing

finite state machine

A system can be in a finite number of different states — this can be described as a finite state machine, shown visually as a state diagram. Any system where you get a different output for the same input, depending on what happened before, is a finite-state system. Transitions from one state to another are determined by the rules of the "machine."

Worked example — ATM PIN entry. States: S1 Start, S2 Wait for PIN, S3 1st try, S4 2nd try, S5 3rd try, S6 Access to account, S7 Eat card. Events: Card inserted, Enter PIN, PIN OK, PIN not OK. Flow: Start →(card inserted)→ Wait for PIN →(enter PIN)→ 1st try →(PIN OK)→ Access to account, or 1st try →(PIN not OK)→ 2nd try →(PIN not OK)→ 3rd try →(PIN not OK)→ Eat card.
State / event table (excerpt)
Card insertedEnter PINPIN OKPIN not OK
S1 StartS2
S2 Wait for PINS3
S3 1st tryS6S4
S4 2nd tryS6S5
S5 3rd tryS6S7
S6 Access to acct.
S7 Eat cardS1

Invalid or null transitions are the dashes () — e.g. you cannot go straight from "Start" to "PIN OK" without inserting a card first.

Why state transition testing?

Because a system may respond differently depending on current conditions or previous history. It lets the tester view the software in terms of: its states, transitions between states, the events that trigger transitions, and the actions that may result.

Tests can be designed to
  • Cover a typical sequence of states
  • Exercise specific sequences of transitions
  • Cover every state
  • Exercise every transition
  • Test invalid transitions
Heavily used throughout the software industry and technical automation in general — anywhere a "mode" or "session" concept exists.
§ 09 — TECHNIQUE 5

Use Case Testing

Instead of testing one input at a time, walk a whole business transaction from start to finish, the way a real user would experience it.

🎭
Memory hook
"Actors set the scene, extensions tell the rest of the story."
A use case's main success scenario is the mainstream (most likely) path; its extensions are the alternative branches (errors, edge paths) that happen off that main path.

Use Case Testing

actor ↔ system interactions

A use case describes interactions between actors (users and the system), which produce a result of value to a system user. Test cases are identified that exercise the whole system on a transaction-by-transaction basis, from start to finish, describing interactions between actor and system in the language of the business rather than technical terms — especially when the actor is a business user.

Anatomy of a use case
Use case name<name>
Actor(s)<actor1>, ...
Pre-conditionsmust be met for the use case to work
Main success scenarionumbered A: action / S: response steps
Extensionsalternative branches: <cause> → S: <response>
Post-conditionsobservable results / final state after completion
Worked example — ATM card entry use case
StepDescription
1A: Inserts card
2S: Validates card and asks for PIN
3A: Enters PIN
4S: Validates PIN
5S: Allows access to account
2aExt: Card not valid → S: Display message, reject card
4aExt: PIN not valid → S: Display message, ask retry (twice)
4bExt: PIN invalid 3× → S: Eat card and exit
Another worked example — online training website: actors are the Learner, the Instructor/Tutor, the Training Manager, and the Instructional Designer, each with different use cases (Register for a course, Launch self-paced course, Author content, Participate in discussions, Receive reports from the HR Management System).
Very useful for designing acceptance tests with customer/user participation. Describes the "process flows" through a system based on its actual likely use, and is most useful for uncovering integration defects — defects caused by incorrect interaction between components that individual/unit testing would never see. Test cases from use cases can be combined with the other specification-based techniques above.
📇
Memory hook — the whole toolkit
"Every Bug Demands State Usage."
Equivalence partitioning · Boundary value analysis · Decision tables · State transition · Use case testing — the five specification-based techniques, in the order this deck teaches them.
§ 10 — GENERAL TESTING

Beyond correctness: the "-ility" tests

Functional black-box techniques ask "does it produce the right output?" This set of general testing types asks broader questions about how the system behaves under real-world conditions.

⏱️

Race Conditions & Timing

Many systems run concurrent activities (OS interrupts, servers with many clients, multi-action apps). Test concurrency scenarios that share resources and may conflict. "Race conditions" only appear when activities interleave in particular ways — hard to reproduce. Test on hardware of varying speeds.

📈

Performance Testing

Measure running times of tasks, memory usage (incl. leaks), network usage (bandwidth, open connections), disk usage (footprint, temp-file cleanup), and process/thread priorities. Tools: IBM Rational Performance Tester, Apache JMeter, WebLOAD, LoadRunner.

🚧

Limit Testing

Test the system at the limits of normal use — every documented limit (max concurrent users/connections, max open files, max request/file size). What happens just beyond the specified limit — graceful degradation, or a crash?

🔥

Stress Testing

Test under extreme conditions, beyond normal-use limits: low memory, disk faults (read/write failures, full disk, corruption), network faults, unusually high request counts/sizes/data rates. An excellent way to find bugs even if the system never needs to run this way in production.

🔐

Security Testing

Any system handling sensitive data/functions is a target. Ask: how feasible is it to break in? Learn hacker techniques, try attacks, or hire a security expert. If someone broke in — or an authorized user turned malicious — what damage could they do? Tools: Metasploit, W3af, Zed Attack Proxy (ZAP), Wapiti.

🖱️

Usability Testing

Is the UI intuitive, organized, logical? Does it frustrate users? Are common tasks simple? Does it follow platform conventions? Get real users to perform tasks, watch for trouble, collect feedback, and log bugs. Tools: Crazy Egg, Optimizely, Usabilla.

♻️

Recovery Testing

Crash the program (or cut power) at arbitrary points. Does it restart correctly? Was persistent data corrupted? Was data loss within acceptable limits? Can it recover from corrupted/deleted config files? Does it need to survive hardware failures?

🖥️

Configuration Testing

Test on all required hardware configs (CPU, memory, disk, graphics, network card) and all required OS versions — virtualization (VMWare, Virtual PC) helps here. Test as many hardware/OS combinations as feasible, including installers.

🔄

Compatibility Testing

Confirm the program works with the other programs it's supposed to interoperate with — e.g. can Word 12.0 load files from Word 11.0? Does "Save As…" really export to Word, WordPerfect, PDF, HTML, Plain Text? Test every stated compatibility requirement.

📚

Documentation Testing

Test every instruction in the documentation for completeness and accuracy. "How To..." guides are notorious for drifting out of sync with UI changes. Test docs on real users to confirm they're clear and complete.

§ 11 — EXPERIENCE-BASED TESTING

When the spec runs out, intuition takes over

Tests derived from the tester's skill, intuition, and experience with similar applications and technologies — best used to augment systematic techniques, not replace them.

🕵️
Memory hook
"Guess the error, explore the gaps."
Error guessing anticipates specific defects from experience; exploratory testing is broader, unscripted investigation of a whole area (concurrent design + execution + logging + learning) guided by a test charter, run in time-boxes.

Error Guessing

The most commonly used experience-based technique. Testers generally anticipate defects based on experience. A structured approach — enumerate a list of possible errors and design tests that attack them — is called fault attack.

Exploratory Testing

Concurrent test design, execution, logging, and learning, based on a test charter of objectives, carried out within time-boxes. Most useful where specs are few/inadequate, under severe time pressure, or to complement more formal testing — it can help ensure the most serious defects surface.

Special Value Testing

The most widely practiced form of functional testing. The tester uses domain knowledge, experience, or intuition to probe areas of probable errors. Other names: "hacking," "out-of-box testing," "ad hoc testing," "seat of the pants testing," "guerilla testing."

  • Uses: complex mathematical/algorithmic calculations, worst-case situations (similar to robustness), problematic situations from past experience, "second guessing" the likely implementation.
  • Characteristics: experience really helps, frequently done by the customer or user, defies measurement, highly intuitive, seldom repeatable — but often very effective.

Choosing test techniques

There's no single "best" technique — the right choice depends on: type of system · time and budget · development life-cycle · regulatory standards · customer requirements · contractual requirements · test objectives · level of risk · type of risk · documentation available · use case models · knowledge of the testers · previous experience with types of defects found.

§ 12 — CHEAT SHEET

The five techniques, in one table

TechniqueCore ideaUse when...Worked example from the deck
Equivalence PartitioningDivide input domain into classes that behave the same; test one representative per classInput is defined as ranges or discrete sets of valuesInteger -99..99, phone number, ZIP code
Boundary Value AnalysisTest min, just-above-min, nominal, just-below-max, maxAlways — as a companion to equivalence partitioningArea code boundary bug: < vs
Decision Table TestingTruth-table every combination of Boolean conditions → resulting actionBusiness rules with several independent T/F conditionsCredit card discount rules (new/loyalty/coupon)
State Transition TestingModel the system as states + events + transitions + actionsSame input gives different output depending on historyATM PIN entry (3 tries then eat card)
Use Case TestingWalk a full actor↔system transaction, main scenario + extensionsTesting end-to-end business workflows / acceptance testingATM card entry; online training website roles
Start here
What does the input/behavior look like?
A range, set, or formatted value?
→ Equivalence Partitioning, then Boundary Value Analysis on its edges.
Several independent Boolean conditions driving an outcome?
→ Decision Table Testing.
Same input, different output depending on history?
→ State Transition Testing (model states/events/transitions).
A full business transaction end-to-end?
→ Use Case Testing (main scenario + extensions).
§ 13 — COMMON MISTAKES

Where students actually lose marks

Seven confusions that show up again and again on exams for this chapter.

1. Treating equivalence partitioning and boundary value analysis as the same technique

✗ WRONG"I did equivalence partitioning, so I don't need boundary value analysis too."
✓ RIGHTBVA is an extension of equivalence partitioning, not a substitute. EP picks one representative per class (often a "center" value); BVA specifically targets the edges of those same classes, because errors cluster at boundaries, not centers.

2. Writing the boundary condition with the wrong comparison operator

✗ WRONGif (200 < areaCode && areaCode < 999) for a valid range of [200, 999]
✓ RIGHTif (200 <= areaCode && areaCode <= 999) — using strict < silently excludes the boundary values themselves. Testing exactly at 200 and 999 (not just a mid-range value like 770) is what catches this.

3. Mixing up how many valid/invalid classes a condition produces

✗ WRONGAssuming every input condition always yields 1 valid class and 2 invalid classes.
✓ RIGHTRanges and specific values → 1 valid + 2 invalid (below and above). Sets and Booleans → 1 valid + 1 invalid (there's no "below" or "above" a set membership or a Boolean).

4. Listing 2ⁿ raw decision-table rules instead of consolidating with "don't care"

✗ WRONGTreating every one of the 2ⁿ combinations as a distinct, meaningful, non-mergeable rule.
✓ RIGHTWhen a condition doesn't affect the outcome for a given combination, mark it "—" (don't care) and merge rules — e.g. the credit-card example collapses Rule 1 & 2 (both invalid regardless of the coupon flag) into one column.

5. Reading a dash ("—") in a state/event table as a valid transition

✗ WRONG"There's a cell in the table for Start→PIN OK, so that transition is allowed."
✓ RIGHTA dash marks an invalid or null transition — that event simply cannot fire from that state. Only cells containing a next-state label (S2, S3, S6...) are real, valid transitions, and testing invalid transitions on purpose is part of thorough state-transition testing.

6. Calling black-box testing "random" or "guessing"

✗ WRONG"Black box testing just means throwing random inputs at the program since you can't see the code."
✓ RIGHTBlack-box testing is systematic: test cases are derived from the specification using techniques like equivalence partitioning and decision tables. Unscripted, intuition-driven testing is a separate category — experience-based testing (error guessing, exploratory testing, special value testing).

7. Confusing use case testing with state transition testing

✗ WRONG"They're basically the same — both use diagrams with boxes and arrows."
✓ RIGHTState transition testing models the system's internal states (open/closed, active/inactive) and what triggers moves between them. Use case testing models a business-level interaction between an actor and the system, expressed in business language, with a main success scenario and extensions — the two can absolutely be combined, but they answer different questions.
§ 14 — POP QUIZ

Quick self-check — click a question to reveal the answer

No grading, no pressure. If you get one wrong, jump back to that section above before moving on.

1. (MC) A test condition specifies an input range of 18–65 (age eligibility). How many valid and invalid equivalence classes does this produce?Reveal
1 valid + 2 invalid
Valid: [18,65]. Invalid: age < 18 and age > 65 — a range always produces one valid class and two invalid classes (below and above).
2. (Short answer) Why does boundary value analysis exist even though equivalence partitioning already picks representative values from every class?Reveal
Because errors cluster at the edges, not the center
A greater number of errors occur at the boundaries of the input domain than in the "center." EP alone might pick a safe, central representative value (like 770 for a 200–999 range) that never triggers an off-by-one bug at 200 or 999.
3. (MC) In a decision table with 3 Boolean conditions, what is the maximum number of rule columns before any consolidation?Reveal
2³ = 8 rules
Each of the 3 conditions can independently be True or False, giving 2×2×2 = 8 raw combinations — matching the credit-card discount example (Rule 1 through Rule 8) before any dashes/merging.
4. (Short answer) What's the difference between a "state" and an "event" in state transition testing?Reveal
A state is a condition the software occupies; an event triggers a move between states
E.g. "Wait for PIN" is a state; "Enter PIN" is the event that transitions the system out of that state. Actions (like an error message) can result from a transition.
5. (MC) Which technique is most useful for designing acceptance tests with customer/user participation, expressed in business rather than technical language?Reveal
Use Case Testing
Use case testing describes actor↔system interactions using business terms, especially when the actor is a business user — and it's specifically called out as very useful for acceptance testing.
6. (Short answer) What single root cause let the Knight Capital bug ship to production in 2012, even though it originated in 2005?Reveal
A defective, unused function was left in the codebase instead of removed
The function was "not meant to be used" but was kept in; new code deployed in 2012 triggered it under new rules, and Knight also ignored the warning emails the system generated — a combination of dead code plus inadequate deployment/testing controls.
7. (MC) A field accepts one of a fixed enumerated set, e.g. {Visa, MasterCard, Discover}. How many valid/invalid equivalence classes does that produce?Reveal
1 valid + 1 invalid
A member-of-a-set condition (like a Boolean) produces exactly one valid class (the set itself) and one invalid class (any value not in the set) — unlike a range, which produces two invalid classes.
8. (Short answer) Name the "Single Defect Assumption" and explain why it matters for functional testing.Reveal
Failures are rarely caused by two or more defects acting at once
Because of this assumption, testing representative combinations of inputs (rather than every possible combination of every possible defect) is usually sufficient — it's part of why equivalence partitioning's "test one value per class" strategy is defensible rather than reckless.
§ 15 — PRACTICE LAB

Apply the right technique to the requirement

Realistic exam-style questions built from the exact examples used in this deck — drill these until picking the right technique becomes automatic.

1. A ZIP code lookup field accepts a 5-digit US postal code and returns a list of cities. Design representative test values for this field.
→ Equivalence Partitioning (+ Boundary Value Analysis)
Why: the input is a formatted value with a defined length. Valid classes: correct zip code with 0, 1, or many matching cities. Invalid classes: empty, 1–4 characters, 6 characters, very long, non-digit characters, non-character data — with boundary values (0 cities, 6 characters) layered on top.
2. A credit-card sign-up page gives 15% off for new customers, 10% off for loyalty-card holders, and 20% off for coupon holders (not combinable with the new-customer discount). Which technique models this, and why?
→ Decision Table Testing
Why: three independent Boolean conditions (new customer? loyalty card? coupon?) combine to determine one output (the discount rate) — the textbook case for a cause-effect decision table.
3. An ATM locks the card after 3 consecutive incorrect PIN entries, but allows access immediately on a correct PIN at any of the 3 tries. What technique models this behavior, and why not just test "enter wrong PIN" and "enter right PIN" as two independent test cases?
→ State Transition Testing
Why: the outcome of "enter PIN" depends on how many previous attempts failed — the same input (a PIN) produces different results (retry vs. lockout) depending on history. That's exactly the definition of a finite-state system.
4. An online banking acceptance test needs to verify the full flow of a customer logging in, transferring funds, and logging out, described in language the customer's business stakeholders can review and sign off on.
→ Use Case Testing
Why: this is a full actor↔system transaction from start to finish, described for a business audience (not developers) — the definition of use case testing, and explicitly the technique recommended for acceptance testing with customer participation.
5. A phone number field requires area code in [200,999], prefix in (200,999], and a 4-digit suffix. List two boundary test values for the area code alone.
→ 199, 200, 201, 998, 999, 1000 (any two)
Why: boundary value analysis tests values just below, at, and just above each edge of the valid range — here the edges are 200 and 999.