pestphp/pest · critical · RuntimeException
Unable to create test case for test file at [%s]. %s
Error message
Unable to create test case for test file at [%s]. %s
What it means
For every test file, TestCaseFactory generates a PHP test-case class (filename constant, trait code, method code) and evals it. If the generated source fails to parse, the ParseError is caught and rethrown as a RuntimeException containing the test file path and the full generated class code — so the exception message doubles as a debugging dump of what Pest built. It is rare and usually signals either an exotic test file or a Pest code-generation bug.
Source
Thrown at src/Factories/TestCaseFactory.php:172
use Pest\Exceptions\DatasetProviderError as __PestDatasetProviderError;
use Pest\Repositories\DatasetsRepository as __PestDatasets;
use Pest\TestSuite as __PestTestSuite;
$attributesCode
#[\AllowDynamicProperties]
final class $className extends $baseClass implements $hasPrintableTestCaseClassFQN {
$traitsCode
public static \$__filename = $filenameLiteral;
$methodsCode
}
PHP;
eval($classCode);
} catch (ParseError $caught) {
throw new RuntimeException(sprintf(
"Unable to create test case for test file at [%s]. \n %s",
$filename,
$classCode
), 1, $caught);
}
}
public function addMethod(TestCaseMethodFactory $method): void
{
if ($method->description === null) {
throw new TestDescriptionMissing($method->filename);
}
if (array_key_exists($method->description, $this->methods)) {
throw new TestAlreadyExist($method->filename, $method->description);
}
if (View on GitHub (pinned to 1af74a215c)
Solutions
- Read the generated class code embedded in the exception message and locate the malformed fragment — usually the method name or trait list derived from your test file.
- Simplify/rename the offending pieces: ASCII filenames, plain test descriptions, standard uses() usage; then re-run.
- Reinstall a clean dependency tree (rm -rf vendor composer.lock && composer install) to rule out half-upgraded codegen.
- If the generated code looks wrong for a normal test file, report it to pestphp/pest including the message — it is likely a codegen bug.
Example fix
// before: test file with an exotic name "2024‑07 ✔.php" -> generated class fails to parse // after: rename the file to plain ASCII git mv "tests/2024-07 ✔.php" tests/ReleaseSmokeTest.php
Defensive patterns
Strategy: try-catch
Try / catch
try {
$factory->buildTestCaseFor($filename);
} catch (RuntimeException $e) {
// message embeds the generated class code — dump it for the bug report
file_put_contents(__DIR__.'/pest-generated-dump.php', $e->getMessage());
throw $e;
} Prevention
- Keep test filenames and descriptions plain ASCII identifiers.
- After major Pest/PHP upgrades, run a clean vendor reinstall before debugging codegen errors.
- If you generate Pest test files programmatically, run them through php -l in CI to catch unparseable output early.
- Report reproducible codegen ParseErrors upstream with the embedded generated class.
When it happens
Trigger: A test file whose name or test descriptions produce class/method code the generator cannot quote safely; trait composition (uses()) injecting code that breaks the generated class; version mismatches after upgrading Pest or PHP where codegen assumptions changed; eval() disabled is not the cause here (that raises a different error) — a genuine parse failure is.
Common situations: Upgrading Pest across major versions with stale caches or mixed old/new vendor files; unusual filenames (spaces, unicode) for test files; projects generating Pest files programmatically with unescaped content; PHP version changes altering acceptable syntax in eval'd code.
Related errors
- The test directory [%s] does not exist.
- Cached failure
- The test expects [%d] argument(s), but the dataset only prov
- Expectation value is not iterable.
- No sequence expectations defined.
AI-assisted analysis of pestphp/pest@1af74a215c (2026-08-21).
Data as JSON: /api/errors/43e81e23b1419d90.
Report an issue: GitHub.