{"record":{"id":"81eb3af65ffaa0c6","repo":"sebastianbergmann/phpunit","slug":"test-file-s-not-found","errorCode":null,"errorMessage":"Test file \"%s\" not found","messagePattern":"Test file \"(.+?)\" not found","errorType":"validation","errorClass":"PHPUnit\\TextUI\\TestFileNotFoundException","httpStatus":null,"severity":"error","filePath":"src/TextUI/Configuration/TestSuiteBuilder.php","lineNumber":77,"sourceCode":"    public function build(Configuration $configuration): TestSuite\n    {\n        $numberOfRuns = $configuration->repeat();\n        $maxAttempts  = $configuration->retry();\n\n        if ($numberOfRuns > 1) {\n            // the --repeat CLI option takes precedence over the --retry CLI option\n            $maxAttempts = 1;\n        }\n\n        if ($configuration->hasCliArguments() || $configuration->hasTestFilesFile()) {\n            $arguments = [];\n\n            if ($configuration->hasCliArguments()) {\n                foreach ($configuration->cliArguments() as $cliArgument) {\n                    $argument = realpath($cliArgument);\n\n                    if ($argument === false) {\n                        throw new TestFileNotFoundException($cliArgument);\n                    }\n\n                    $arguments[] = $argument;\n                }\n            }\n\n            if ($configuration->hasTestFilesFile()) {\n                if (!is_file($configuration->testFilesFile())) {\n                    throw new RuntimeException('Cannot read from ' . $configuration->testFilesFile());\n                }\n\n                $directory = dirname($configuration->testFilesFile()) . DIRECTORY_SEPARATOR;\n\n                $fileLines = file($configuration->testFilesFile());\n\n                // @codeCoverageIgnoreStart\n                if ($fileLines === false) {\n                    throw new RuntimeException('Cannot read from ' . $configuration->testFilesFile());","sourceCodeStart":59,"sourceCodeEnd":95,"githubUrl":"https://github.com/sebastianbergmann/phpunit/blob/f123cdb2a2d49f15025794166cfed8bda8627dd2/src/TextUI/Configuration/TestSuiteBuilder.php#L59-L95","documentation":"TestSuiteBuilder::build() runs realpath() on every test file named on the command line; realpath() returns false when the path does not exist, and the Builder throws PHPUnit\\TextUI\\TestFileNotFoundException with the path exactly as given. This happens before any test is loaded, so nothing runs.","triggerScenarios":"`vendor/bin/phpunit tests/Unit/UserTest.php` after the file was renamed to AccountTest.php; a typo in the path; a relative path used from a different working directory than assumed (e.g. running from tests/ instead of the project root).","commonSituations":"Test files renamed or moved during a refactor while scripts/CI configs still reference the old names; CI checking out a different branch with a different file layout; running phpunit from a subdirectory with root-relative paths.","solutions":["Verify the argument exists from your current directory: `ls tests/Unit/UserTest.php` with the exact string you pass","Run from the project root or use an absolute path","Update the stale file reference in your script/CI config after renames","Check `git status` / `git log --follow` to find where the file went"],"exampleFix":"# before (file was renamed to AccountTest.php)\nvendor/bin/phpunit tests/Unit/UserTest.php\n\n# after\nvendor/bin/phpunit tests/Unit/AccountTest.php","handlingStrategy":"validation","validationCode":"$testFile = $argv[1] ?? '';\n\nif ($testFile !== '' && !is_file($testFile)) {\n    fwrite(STDERR, \"Test file not found: {$testFile} (cwd: \" . getcwd() . ')' . PHP_EOL);\n    exit(2);\n}\n\n// safe to pass to phpunit now","typeGuard":null,"tryCatchPattern":"try {\n    $suite = (new \\PHPUnit\\TextUI\\Configuration\\TestSuiteBuilder)->build($configuration);\n} catch (\\PHPUnit\\TextUI\\TestFileNotFoundException $e) {\n    // $e->getMessage() contains the exact unresolved argument;\n    // verify cwd and file existence, fix the argument, and retry\n}","preventionTips":["Always run phpunit from the project root or use absolute paths in scripts","After renaming/moving test files, grep your CI configs and scripts for the old paths","Validate dynamically generated file arguments with is_file() before invoking the runner"],"tags":["phpunit","cli","test-selection","file-not-found","realpath"],"backgroundTag":"test-file-not-found","analyzedSha":"f123cdb2a2d49f15025794166cfed8bda8627dd2","analyzedAt":"2026-08-23T01:20:58.058Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}