pestphp/pest · error · TestAlreadyExist

A test named [%s] already exists in [%s]. Please give this t

Error message

A test named [%s] already exists in [%s]. Please give this test a different description.

What it means

Within a single test file, Pest registers each test by its description; addMethod throws TestAlreadyExist when a description already exists in that file's test case. The check is an exact array_key_exists on the description string, so two tests with the identical description collide even if their bodies differ.

Source

Thrown at src/Factories/TestCaseFactory.php:187

            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 (
            $method->closure instanceof \Closure &&
            new \ReflectionFunction($method->closure)->isStatic()
        ) {

            throw new TestClosureMustNotBeStatic($method);
        }

        if (! $method->receivesArguments()) {
            if (! $method->closure instanceof \Closure) {
                throw ShouldNotHappen::fromMessage('The test closure may not be empty.');
            }

            $arguments = Reflection::getFunctionArguments($method->closure);

            if ($arguments !== []) {

View on GitHub (pinned to 1af74a215c)

Solutions

  1. Rename the second test to a unique description in that file.
  2. Make duplicated cases data-driven instead of copy-pasted: one test + ->with([[...], [...]]).
  3. Prefix titles inside describe blocks if you intentionally repeat inner names (check the file's other descriptions first — the message names both file and description).

Example fix

// before
it('validates email', fn () => ...);
it('validates email', fn () => ...); // duplicate
// after
it('validates email format', fn () => ...);
it('validates email domain', fn () => ...);
Defensive patterns

Strategy: validation

Validate before calling

// guard in test-generator helpers:
static $seen = [];
if (isset($seen[$description])) {
    throw new LogicException("Duplicate test description [{$description}]");
}
$seen[$description] = true;
test($description, $closure);

Prevention

When it happens

Trigger: Two it('creates a user', ...) blocks in the same file (classic copy-paste); dataset-driven tests where the same description template is reused without interpolation; describe() blocks in one file reusing the same inner test name across different describes (Pest namespaces describes in output but the factory keys per file).

Common situations: Copy-paste test growth; merging branches that both added a test with the same title; refactoring big files by duplicating a block and intending to edit the title later; non-descriptive titles ('works', 'test 1') colliding.

Related errors


AI-assisted analysis of pestphp/pest@1af74a215c (2026-08-21). Data as JSON: /api/errors/89432bb3641c888f. Report an issue: GitHub.