sebastianbergmann/phpunit · error · ExpectationFailedException

Expected deprecation with message "%s" was not triggered

Error message

Expected deprecation with message "%s" was not triggered

What it means

Thrown after the test body finishes when expectDeprecation() was called but DeprecationCollector never recorded a matching user deprecation. PHPUnit verifies outstanding deprecation expectations in verifyDeprecationExpectations() during runBare(), so a missing deprecation is treated as a failed assertion.

Source

Thrown at src/Framework/TestCase.php:1505

            $this->errorLogCapture->stop();
        }

        $this->emitEventForCustomTestMethodInvocation();
        $this->exceptionExpectation->assertWasRaised($this);

        return $testResult;
    }

    /**
     * @throws ExpectationFailedException
     */
    private function verifyDeprecationExpectations(): void
    {
        foreach ($this->expectedUserDeprecationMessage as $deprecationExpectation) {
            $this->numberOfAssertionsPerformed++;

            if (!in_array($deprecationExpectation, DeprecationCollector::deprecations(), true)) {
                throw new ExpectationFailedException(
                    sprintf(
                        'Expected deprecation with message "%s" was not triggered',
                        $deprecationExpectation,
                    ),
                );
            }
        }

        foreach ($this->expectedUserDeprecationMessageRegularExpression as $deprecationExpectation) {
            $this->numberOfAssertionsPerformed++;

            $expectedDeprecationTriggered = array_any(
                DeprecationCollector::deprecations(),
                static fn (string $deprecation) => @preg_match($deprecationExpectation, $deprecation) > 0,
            );

            if (!$expectedDeprecationTriggered) {
                throw new ExpectationFailedException(

View on GitHub (pinned to f123cdb2a2)

Solutions

  1. Verify the code under test actually executes the branch that triggers the deprecation in this test
  2. Compare the expected string byte-for-byte with the trigger_error() message; fix typos or interpolated values
  3. Switch to expectDeprecationMatch() with a regex when the message contains variable parts
  4. Ensure the deprecation is triggered in the same PHP process (avoid process isolation for this test)

Example fix

// before
$this->expectDeprecation('Using Config v2 is deprecated');
$api->load("v3"); // never touches the deprecated v2 path

// after
$this->expectDeprecation('Using Config v2 is deprecated');
$api->load("v2"); // exercises the deprecated path
Defensive patterns

Strategy: validation

Validate before calling

// Before the test: confirm the expected deprecation is among collected ones in this process
$this->expectDeprecation('Config v2 is deprecated');
$api->load('v2');
self::assertContains(
    'Config v2 is deprecated',
    DeprecationCollector::deprecations(),
);

Try / catch

// When wrapping third-party tests, let the failure surface instead of swallowing it:
try {
    $test->runBare();
} catch (ExpectationFailedException $e) {
    if (!str_contains($e->getMessage(), 'Expected deprecation with message')) {
        throw $e;
    }
    // record as deprecation-missing failure
}

Prevention

When it happens

Trigger: Calling $this->expectDeprecation('exact message') but the code under test never calls trigger_error($msg, E_USER_DEPRECATED) with exactly that message, or the deprecation fires in a separate process from the one collecting them.

Common situations: Message typos or dynamic parts in the deprecation string (use expectDeprecationMatch() for those); the deprecated code path not being reached by this test; process isolation splitting the collector; library versions changing deprecation wording.

Related errors


AI-assisted analysis of sebastianbergmann/phpunit@f123cdb2a2 (2026-08-23). Data as JSON: /api/errors/d7af430359cb5d4c. Report an issue: GitHub.