{"record":{"id":"eb6331843674318f","repo":"sebastianbergmann/phpunit","slug":"test-file-s-not-found-eb6331","errorCode":null,"errorMessage":"Test file \"%s\" not found","messagePattern":"Test file \"(.+?)\" not found","errorType":"exception","errorClass":"PHPUnit\\TextUI\\TestFileNotFoundException","httpStatus":null,"severity":"error","filePath":"src/TextUI/Configuration/Xml/TestSuiteMapper.php","lineNumber":132,"sourceCode":"                        $empty            = false;\n\n                        if ($this->skipper->canSkipLoading($file, $groups)) {\n                            continue;\n                        }\n\n                        $this->skipper->record(\n                            $file,\n                            static function () use ($testSuite, $file, $groups, $numberOfRuns, $maxAttempts): void\n                            {\n                                $testSuite->addTestFile($file, $groups, $numberOfRuns, $maxAttempts);\n                            },\n                        );\n                    }\n                }\n\n                foreach ($configuredTestSuite->files() as $file) {\n                    if (!is_file($file->path())) {\n                        throw new TestFileNotFoundException($file->path());\n                    }\n\n                    if (!version_compare(PHP_VERSION, $file->phpVersion(), $file->phpVersionOperator()->asString())) {\n                        continue;\n                    }\n\n                    if ($this->wasAlreadyAddedToAnotherTestSuite($processed, $file->path(), $testSuiteName)) {\n                        continue;\n                    }\n\n                    $processed[$file->path()] = $testSuiteName;\n                    $empty                    = false;\n\n                    if ($this->skipper->canSkipLoading($file->path(), $file->groups())) {\n                        continue;\n                    }\n\n                    $this->skipper->record(","sourceCodeStart":114,"sourceCodeEnd":150,"githubUrl":"https://github.com/sebastianbergmann/phpunit/blob/f123cdb2a2d49f15025794166cfed8bda8627dd2/src/TextUI/Configuration/Xml/TestSuiteMapper.php#L114-L150","documentation":"The <file> counterpart of the directory check: TestSuiteMapper::map() runs is_file() on every <file> entry of a <testsuite> and throws PHPUnit\\TextUI\\TestFileNotFoundException with the configured path when it does not exist. Unlike <directory> entries, there is no wildcard exemption.","triggerScenarios":"`<file>tests/SmokeTest.php</file>` where the file was deleted or renamed; case mismatches between the XML and the filesystem (developing case-insensitively on macOS/Windows, CI running case-sensitively on Linux); a single-file suite entry left behind after a split-up.","commonSituations":"Renamed or deleted test files still listed in phpunit.xml; case-sensitivity differences between developer machines and Linux CI; files moved during refactors.","solutions":["Update or remove the stale <file> entry in phpunit.xml","Fix casing so the XML matches the filesystem byte-for-byte (critical for Linux CI)","Prefer <directory> with suffix filters over long <file> lists when files churn"],"exampleFix":"<!-- before -->\n<testsuite name=\"smoke\">\n  <file>tests/smoketest.php</file>\n</testsuite>\n\n<!-- after (actual name is SmokeTest.php) -->\n<testsuite name=\"smoke\">\n  <file>tests/SmokeTest.php</file>\n</testsuite>","handlingStrategy":"validation","validationCode":"$configDir = dirname(realpath('phpunit.xml'));\n$xml = simplexml_load_file('phpunit.xml');\n\nforeach ($xml->xpath('//testsuite/file') as $file) {\n    $path = (string) $file;\n\n    if (!is_file($configDir . DIRECTORY_SEPARATOR . $path) && !is_file($path)) {\n        fwrite(STDERR, \"Configured test file missing: {$path}\" . PHP_EOL);\n        exit(2);\n    }\n}","typeGuard":null,"tryCatchPattern":"try {\n    $suite = (new \\PHPUnit\\TextUI\\XmlConfiguration\\TestSuiteMapper)->map(...);\n} catch (\\PHPUnit\\TextUI\\TestFileNotFoundException $e) {\n    // message names the missing <file> path; remove or correct the entry (watch filename casing on Linux)\n}","preventionTips":["Remove or update <file> entries when the referenced tests are renamed or deleted","Match filename casing exactly; case-insensitive local filesystems hide mismatches until Linux CI","Prefer <directory suffix=\"...\"> over long <file> lists when files change often"],"tags":["phpunit","xml","test-suite","file-not-found","configuration","case-sensitivity"],"backgroundTag":"test-file-not-found","analyzedSha":"f123cdb2a2d49f15025794166cfed8bda8627dd2","analyzedAt":"2026-08-23T01:20:58.058Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}