sebastianbergmann/phpunit · error · CodeCoverageDriverException

Configured code coverage driver class

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.

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.

Appendix: 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)