PHP / CHAPTER 13
Boundary tests and exact outcomes
AdvancedTest observable contracts without confusing equality and coercion.
By the end of this chapter
- Use strict expected-value comparisons
- Test shape, order, and duplicates
- Verify rejected operations preserve state
The idea
A test should distinguish the outcomes that matter to callers. Strict comparisons can separate false, zero, null, and empty strings when an API assigns them different meanings. If a function reports absence with null, a valid zero should not satisfy the same failure assertion. Test returned data shape as well as values, especially when array keys and list reindexing are part of the contract.
Choose cases that target known algorithm risks. Consecutive removed values reveal index-shifting bugs; duplicate maximum values reveal tie policy; all-negative input reveals an incorrect zero initializer. For mutation-sensitive APIs, snapshot the relevant state and compare it after both successful and rejected operations. Expected failures should be checked through the documented result or exception rather than accepting any unexpected runtime error as evidence of correct rejection.
<?php
function parseCount(string $text):?int {if(!preg_match("/\A[0-9]+\z/",$text))return null;$n=filter_var($text,FILTER_VALIDATE_INT);return $n===false?null:$n;}
if(parseCount("0")!==0||parseCount("x")!==null)throw new RuntimeException("failed");
echo "checks passed\n";checks passed
Strict checks verify that a valid zero remains distinct from an invalid-input null result.
Try it yourself
Test a stable filtering function for empty input, repeated accepted values, preserved order, and expected keys.
Use your own editor for this exercise. Runnable challenges on CodeQuest are available for JavaScript, Python, and SQL.
CHECK YOUR UNDERSTANDING