AI disclosure: An AI agent drafted this article by reading an existing Python example. The tables specify expected behavior from source; they are not test results. No API was called and no new test implementation is supplied.
A useful boundary case starts with the predicate the program evaluates. An error message is a clue, but its wording may be less precise than the condition that triggers it.
Consider a small support-drafting function. Before calling its request helper, it rejects a blank ticket, rejects a ticket whose length is greater than 8,000, and requires an output-token parameter between 1 and 2,048 inclusive.
These are limits of the example function. They do not establish the API service's limits or the capabilities of any model.
Hold the other inputs steady
To reason about one check, choose otherwise valid local inputs and vary only the item under discussion. If both the ticket and the numeric parameter are invalid, an early failure may hide the later condition.
For the ticket, the first question is whether its stripped value is empty. The length check then uses the original string, not the stripped version.
| Proposed ticket case | Expected result at the local ticket checks | Why it is useful |
|---|---|---|
| Empty text | Reject as empty | Covers the obvious empty input. |
| Spaces or newlines only | Reject as empty | Exercises the stripped-value check. |
| Nonblank text of length 7,999 | Pass these ticket checks | Covers just below the upper boundary. |
| Nonblank text of length 8,000 | Pass these ticket checks | Establishes whether equality is allowed. |
| Nonblank text of length 8,001 | Reject as too long | Covers just above the boundary. |
“Pass these checks” is deliberately narrow. It does not mean a model request succeeded, a reply was useful or any charge was established.
The example's error text says to keep the ticket “under” 8,000 characters, while its condition rejects only lengths greater than 8,000. A source-derived case at exactly 8,000 exposes that difference without guessing what the author intended.
The Python documentation defines len() in terms of the number of items. Here it is applied to a decoded string. Do not silently substitute archive size, UTF-8 byte count or a model's token count as the measurement.
Separate parsing from range validation
The command-line path first converts the output-token setting with int(). The function then applies its numeric range check.
| Proposed parameter case | Expected stage |
|---|---|
| A value that cannot be parsed as an integer | Stop during conversion on the command-line path. |
| Integer 0 | Reject at the function's range check. |
| Integer 1 | Pass this range check. |
| Integer 2,048 | Pass this range check. |
| Integer 2,049 | Reject at the function's range check. |
These are separate assertions. An integer-conversion failure does not exercise the upper-bound branch. A valid integer does not establish that it lies within the allowed range.
Keep expectations separate from observations
A case record should have distinct places for the source condition, the expected branch, the observed result and the evidence. Until the case has actually been executed under stated conditions, leave the observed result as not run.
If these cases are later implemented, the external request should be isolated so that passing the local checks cannot accidentally trigger a real call. That is a proposed testing boundary, not a claim that a test harness was built here.
This small matrix gives a reviewer something precise to challenge: equality at the limit, measurement units, conversion versus range validation, and the order of checks. It avoids using a generic “invalid input” case as a substitute for understanding which predicate was exercised.
Top comments (0)