Test With ZOMBIES
ZOMBIES1 is an acronym and a useful test heuristic, especially for developers.
Testing is a complex activity, but using ZOMBIES helps catch easy-to-prevent bugs. Pick the low-hanging fruit, so to speak.
ZOM - Zero, One, Many
Zero and One are edge cases, and Many is the first generalization - if the function or module works correctly with 2 "things", it is likely to work with 3, 4, and more (though far from always).
Zero
For convenience and structure, "Zero" cases are grouped into in-memory and out-of-memory.
In-Memory "Zero" Cases*
Null / None references (standalone variables, inside
List,Set, orMap/dict values)Numeric zero values:
0,0.0NaN (Not a Number)
Empty or blank string (
""," ")Empty collections:
[],{}, emptySetorMap, empty Map values, empty JSON array/objectDefault-constructed / uninitialized objects (all fields at defaults)
Boolean false (logical zero in some contexts)
*Although these originate in memory, zero values can propagate into or come back from external systems, and can occur in an out-of-memory context (see below).
Out-of-Memory (External) "Zero" Cases
Database query results:
No rows returned (
SELECT ...yields an empty result set)Aggregations yielding
0(e.g.,COUNT(*)=0)
File system / I/O:
Zero-length file
Empty stream or socket response
API / Service responses:
Empty JSON/XML response body
Valid response with an empty list or object
nullor missing fields in the payload
Message queues / event buses:
No messages available (empty poll)
One
Exactly "one of the thing" is a frequent edge case too. Exactly one item in a shopping cart, one money transfer, one item in a List of Set.
Consider the loop below. It takes two values at a time and sums them up.
For example, given the input [1,2,3,4], it will compute 1+2, 3+4, and output [3, 7].
But it will fail with input containing just one element.
Many
"If it works with 2 things, it will work with more" is a good starting point as a generalization, but sometimes insufficient. Special, context-dependent values are important.
Even the trivial sum_pairs example above will fail given a collection with an odd number of elements.
"Odd" or "even" count is one example of how a special number may reveal a bug.
See EP&BVA for more special business, numerical, and non-numerical values.
B - Boundary Values
See EP&BVA.
I - Interfaces
Sometimes, programmers get so tangled up in the implementation details that they let implementation dictate or influence the interface (method/function signature, API endpoints, JSON contracts, etc.)
Interfaces exist to benefit the "client" (a human user, another program, a calling function).
This point suggests focusing on the interface first - its usability and clarity.
Working solo: practice TDD to produce cleaner interfaces. With tests, one sees how the function, class, or another smaller piece of code looks and feels when being used by the caller.
Working together: code/design reviews, providing an unimplemented interface to future users to provide feedback on
E - Exercise Exceptional Behavior
Sometimes known as "negative testing" - trigger failures, crashes, timeouts, and write code that is prepared to handle such events gracefully.
Files: absent, locked for reading/writing, interruption during read/write, corrupted content
Network: disconnected, timeout, slow response, invalid data received
User input: unexpected or invalid formats, empty input, extremely large input
System resources: low memory, disk full, CPU spikes
APIs / external services: unavailable, error responses, rate-limited, malformed responses
See Advanced State Testing and Testing Failures and Errors for more ideas.
S - Simple Scenarios, Simple Solutions
A guiding tip that reflects the general TDD approach: when implementing something, imagine simple scenarios first (happy path), and write the simplest possible implementation for that first.
Iterate and handle harder scenarios with more complex code gradually.
References
ZOMBIES was likely originally coined by James Grenning in his blog post. See also "TDD Guided by ZOMBIES" YouTube video.
Last updated