sebastianbergmann/phpunit · error · NoChildTestSuiteException
The current item is not a TestSuite instance and therefore d
Error message
The current item is not a TestSuite instance and therefore does not have any children.
What it means
Thrown by TestSuiteIterator::getChildren() when the current element is a leaf Test (a TestCase) rather than a composite TestSuite. getChildren() must return an iterator over a nested suite, so calling it on a non-container element raises NoChildTestSuiteException after hasChildren() returns false.
Source
Thrown at src/Framework/TestSuiteIterator.php:75
public function current(): Test
{
assert(isset($this->tests[$this->position]));
return $this->tests[$this->position];
}
public function next(): void
{
$this->position++;
}
/**
* @throws NoChildTestSuiteException
*/
public function getChildren(): self
{
if (!$this->hasChildren()) {
throw new NoChildTestSuiteException(
'The current item is not a TestSuite instance and therefore does not have any children.',
);
}
$current = $this->current();
assert($current instanceof TestSuite);
return new self($current);
}
public function hasChildren(): bool
{
return $this->valid() && $this->current() instanceof TestSuite;
}
}
View on GitHub (pinned to f123cdb2a2)
Solutions
- Guard the descent: call hasChildren() (or check $current instanceof TestSuite) before getChildren()
- Handle the leaf case explicitly in your traversal (process the test, do not recurse)
- Use the iterator's standard recursive traversal instead of a hand-written one
Example fix
// before
$children = $iterator->getChildren(); // throws on a TestCase node
// after
if ($iterator->hasChildren()) {
$children = $iterator->getChildren();
} else {
$test = $iterator->current(); // leaf TestCase, process it
} Defensive patterns
Strategy: type-guard
Validate before calling
if ($iterator->hasChildren()) {
$childIterator = $iterator->getChildren();
} Type guard
/** @param TestSuiteIterator<TestCase> $iterator */
function currentIsSuite(TestSuiteIterator $iterator): bool
{
return $iterator->current() instanceof \PHPUnit\Framework\TestSuite;
} Prevention
- Always branch on hasChildren() before getChildren() when walking the iterator tree
- Handle TestCase leaf nodes explicitly in custom reporters/filters
When it happens
Trigger: Calling $iterator->getChildren() while positioned on a TestCase; custom reporters/filters that walk the iterator tree and unconditionally descend instead of checking for children first.
Common situations: Custom test listeners or collectors traversing suites with a recursive algorithm that assumes every node is composite; iterating a flat suite whose direct children are all TestCases.
Related errors
- Class %s is abstract
- Class %s is not a subclass of %s
- The tests aggregated by this TestSuite were already run
- Default test suite is not configured
- Test directory "%s" not found
AI-assisted analysis of sebastianbergmann/phpunit@f123cdb2a2 (2026-08-23).
Data as JSON: /api/errors/12769a8766bac1ee.
Report an issue: GitHub.