{"record":{"id":"4f70793eeec13d14","repo":"pestphp/pest","slug":"the-test-directory-s-does-not-exist","errorCode":null,"errorMessage":"The test directory [%s] does not exist.","messagePattern":"The test directory \\[(.+?)\\] does not exist\\.","errorType":"exception","errorClass":"FatalException","httpStatus":null,"severity":"critical","filePath":"src/Bootstrappers/BootFiles.php","lineNumber":40,"sourceCode":"{\n    /**\n     * @var array<int, string>\n     */\n    private const array STRUCTURE = [\n        'Expectations',\n        'Expectations.php',\n        'Helpers',\n        'Helpers.php',\n        'Pest.php',\n    ];\n\n    public function boot(): void\n    {\n        $rootPath = TestSuite::getInstance()->rootPath;\n        $testsPath = $rootPath.DIRECTORY_SEPARATOR.testDirectory();\n\n        if (! is_dir($testsPath)) {\n            throw new FatalException(sprintf('The test directory [%s] does not exist.', $testsPath));\n        }\n\n        foreach (self::STRUCTURE as $filename) {\n            $filename = sprintf('%s%s%s', $testsPath, DIRECTORY_SEPARATOR, $filename);\n\n            if (! file_exists($filename)) {\n                continue;\n            }\n\n            if (is_dir($filename)) {\n                $directory = new RecursiveDirectoryIterator($filename);\n                $iterator = new RecursiveIteratorIterator($directory);\n                /** @var \\DirectoryIterator $file */\n                foreach ($iterator as $file) {\n                    $this->load($file->__toString());\n                }\n            } else {\n                $this->load($filename);","sourceCodeStart":22,"sourceCodeEnd":58,"githubUrl":"https://github.com/pestphp/pest/blob/1af74a215c3a89bc7a44fc6f9322e369eaad2423/src/Bootstrappers/BootFiles.php#L22-L58","documentation":"Pest computes the test directory as TestSuite rootPath + the value returned by testDirectory() (default 'tests', overridable via the TEST_DIRECTORY env variable or Pest configuration) and verifies it exists during bootstrapping, before any test file loads. When is_dir() fails, BootFiles throws this FatalException and the entire run aborts immediately. It is a configuration/layout error, not a test failure.","triggerScenarios":"Running vendor/bin/pest when the configured TEST_DIRECTORY points to a folder that does not exist; renaming tests/ to specs/ (or moving it into a subdirectory) without updating phpunit.xml's <env name=\"TEST_DIRECTORY\" .../>; running Pest from the wrong working directory so rootPath resolves to a folder without tests; a case mismatch such as Tests/ vs tests/ on a case-sensitive filesystem.","commonSituations":"Fresh clones where the repo keeps tests in a non-default location and the env var is not set; CI pipelines that exclude the tests directory from the checkout artifact; monorepos where vendor/bin/pest is executed from the package root instead of the app root; after a directory restructure the .env or phpunit.xml still names the old path.","solutions":["Check which directory Pest resolves: the message contains the full path — verify it against where your tests actually live, and fix TEST_DIRECTORY in phpunit.xml/.env if it is wrong.","Create the missing directory (mkdir -p tests) if the project genuinely should have one and add a bootstrap Pest.php.","Run vendor/bin/pest from the project root (where composer.json and the tests directory sit) so rootPath is correct.","On case-sensitive filesystems (Linux CI), confirm the directory casing matches exactly (Tests vs tests)."],"exampleFix":"<!-- phpunit.xml -->\n// before\n<php><env name=\"TEST_DIRECTORY\" value=\"specs\"/></php>  <!-- folder is actually \"tests\" -->\n// after\n<php><env name=\"TEST_DIRECTORY\" value=\"tests\"/></php>","handlingStrategy":"validation","validationCode":"// before running pest (CI step or composer script):\n$dir = getcwd().'/'.(getenv('TEST_DIRECTORY') ?: 'tests');\nif (! is_dir($dir)) {\n    fwrite(STDERR, \"Test directory missing: {$dir}\\n\");\n    exit(1);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep the tests directory at the conventional 'tests' path unless a TEST_DIRECTORY override is also configured in phpunit.xml.","Add a CI sanity step that asserts the test directory exists before invoking vendor/bin/pest.","Run pest from the project root (composer test script) so rootPath resolution is deterministic.","After any directory rename, grep phpunit.xml, .env, and CI config for the old path."],"tags":["pest","configuration","bootstrap","filesystem","test-directory"],"backgroundTag":"missing-configured-directory","analyzedSha":"1af74a215c3a89bc7a44fc6f9322e369eaad2423","analyzedAt":"2026-08-21T02:16:38.132Z","schemaVersion":2},"datasetVersion":"2026-08-21T03:17:12.404Z"}