sebastianbergmann/phpunit · error · CodeCoverageDriverException

Configured code coverage driver class "%s" does not extend %

Error message

Configured code coverage driver class "%s" does not extend %s

What it means

The class named in the <coverage driver="..."> attribute exists, but is_subclass_of() showed it is not a subclass of SebastianBergmann\CodeCoverage\Driver\Driver — the contract PHPUnit's coverage subsystem drives. Only Driver subclasses can be instantiated, so activation aborts with this error.

Source

Thrown at src/Runner/CodeCoverage.php:618

    }

    /**
     * @phpstan-ignore return.internalClass
     */
    private function instantiateDriver(string $driverClass, Filter $filter, Granularity $granularity): Driver
    {
        if (!class_exists($driverClass)) {
            throw new CodeCoverageDriverException(
                sprintf(
                    'Configured code coverage driver class "%s" does not exist',
                    $driverClass,
                ),
            );
        }

        /** @phpstan-ignore classConstant.internalClass */
        if (!is_subclass_of($driverClass, Driver::class)) {
            throw new CodeCoverageDriverException(
                sprintf(
                    'Configured code coverage driver class "%s" does not extend %s',
                    $driverClass,
                    /** @phpstan-ignore classConstant.internalClass */
                    Driver::class,
                ),
            );
        }

        $reflection = new ReflectionClass($driverClass);

        if (!$reflection->isInstantiable()) {
            throw new CodeCoverageDriverException(
                sprintf(
                    'Configured code coverage driver class "%s" is not instantiable',
                    $driverClass,
                ),
            );

View on GitHub (pinned to f123cdb2a2)

Solutions

  1. Make the class extend SebastianBergmann\CodeCoverage\Driver\Driver and implement its abstract methods.
  2. Align the php-code-coverage version with what this PHPUnit build expects (composer why-not phpunit/phpunit, then update).
  3. If the custom driver is not maintained, drop the driver attribute and use the built-in driver selector.

Example fix

// before
class MyDriver
{
    public function start(): void {}
    public function stop(): array { return []; }
}

// after
class MyDriver extends \SebastianBergmann\CodeCoverage\Driver\Driver
{
    // implement the abstract methods of the Driver base class
}
Defensive patterns

Strategy: type-guard

Type guard

function isUsableCoverageDriver(string $class): bool
{
    return class_exists($class)
        && is_subclass_of($class, \SebastianBergmann\CodeCoverage\Driver\Driver::class);
}

Prevention

When it happens

Trigger: driver pointing at a class implementing an older php-code-coverage driver interface (version skew after upgrading php-code-coverage), a plain class with a similarly named API, or a wrapper around Xdebug/PCOV functions that never extended Driver.

Common situations: Upgrading PHPUnit/php-code-coverage while keeping a custom driver built against the old API; drivers copied from another project; implementing a same-shaped interface instead of extending the Driver base class.

Related errors


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