sebastianbergmann/phpunit · error · ClassCannotBeFoundException
Class %s cannot be found in %s
Error message
Class %s cannot be found in %s
What it means
TestSuiteLoader::load() (used when you pass a single test file to phpunit, e.g. 'phpunit tests/ExampleTest.php') starts with realpath($suiteClassFile); when realpath() returns false the file does not exist (or is outside open_basedir), and ClassCannotBeFoundException('Class %s cannot be found in %s') is thrown with the path for both placeholders.
Source
Thrown at src/Runner/TestSuiteLoader.php:51
*/
private static ?int $numberOfDeclaredClasses = null;
/**
* @var array<non-empty-string, list<class-string>>
*/
private static array $fileToClassesMap = [];
/**
* @throws Exception
*
* @return ReflectionClass<TestCase>
*/
public function load(string $suiteClassFile): ReflectionClass
{
$resolved = realpath($suiteClassFile);
if ($resolved === false) {
throw new ClassCannotBeFoundException($suiteClassFile, $suiteClassFile);
}
$suiteClassFile = $resolved;
$suiteClassName = $this->classNameFromFileName($suiteClassFile);
$loadedClasses = $this->loadSuiteClassFile($suiteClassFile);
foreach ($loadedClasses as $className) {
/** @noinspection PhpUnhandledExceptionInspection */
$class = new ReflectionClass($className);
if ($class->isAnonymous()) {
continue;
}
if ($class->getFileName() !== $suiteClassFile) {
continue;
}
View on GitHub (pinned to f123cdb2a2)
Solutions
- Check the file path argument for typos and run phpunit from the directory the path is relative to (or pass an absolute path).
- Confirm the file still exists: ls -l tests/ExampleTest.php.
- If the file exists but realpath() still fails, check open_basedir / symlink targets.
Example fix
# before phpunit tests/ExmapleTest.php # typo # after phpunit tests/ExampleTest.php
Defensive patterns
Strategy: validation
Validate before calling
$file = 'tests/ExampleTest.php';
if (!is_file($file)) {
throw new InvalidArgumentException("Test file does not exist: {$file}");
}
$loader = new \PHPUnit\Runner\TestSuiteLoader();
$class = $loader->load($file); Prevention
- Pass absolute paths (or resolve against the project root) when invoking phpunit programmatically or in CI scripts.
- Regenerate IDE run configurations after renaming test files.
- Fail fast with is_file() checks in wrapper scripts that accept file arguments.
When it happens
Trigger: Calling phpunit with a path to a file that does not exist: typo in the filename, wrong working directory, deleted/moved file, or a path blocked by open_basedir so realpath() fails even though the file exists.
Common situations: Typos in CLI arguments or CI scripts; running phpunit from a different directory than assumed; stale IDE run configurations after files were renamed; open_basedir restrictions in hardened environments.
Related errors
- Test file "%s" not found
- Cannot read from %s
- Class or interface "%s" does not exist
- --%s-- is not a valid PHPT section
- Class %s declared in %s does not extend PHPUnit\Framework\Te
AI-assisted analysis of sebastianbergmann/phpunit@f123cdb2a2 (2026-08-23).
Data as JSON: /api/errors/68d444ce90762874.
Report an issue: GitHub.