Skip to main content

Sonda 1.16: branch coverage for PHP without Xdebug, now in English

· 2 min read
Daniel Neto
Author of Sonda

Sonda measures line and branch coverage of a PHP test suite by instrumenting the source instead of hooking the engine. Version 1.16 makes it a project for everyone: the CLI, the README and this site are in English, and the package is on Packagist as ddr/sonda.

Why another coverage tool​

Our CI measured coverage with Xdebug --path-coverage, the only way to get branches in PHP. On a Laravel suite of 4,500 tests it did not finish in an hour. PCOV is fast, but it only counts lines. We wanted "100% of the lines and branches of what this merge request changed" as a merge gate, and nothing could give that in CI time.

What it does​

Sonda inserts a probe at every branch outcome before the file loads, the way Istanbul does for JavaScript. A probe is one array assignment; there is no opcode interception and no path enumeration. On the same suite: 178s without coverage, 174s with Sonda, 671s with Xdebug counting lines only.

The branch semantics are strict by default: an if without else still needs both outcomes, ?-> counts the null side, and &&/|| must short-circuit at least once. The whole suite was compared with Xdebug path coverage, method by method; the comparison page has the numbers and the documented differences.

In CI​

sonda test --changed=origin/master measures only the files the branch changed and fails if any line or branch of them stays uncovered. --affected runs only the tests that executed those files. GitLab gets the Cobertura diff annotations and Code Quality entries for free; there are recipes for GitLab and GitHub Actions.

Getting it​

composer require --dev ddr/sonda
vendor/bin/sonda test

PHP 8.4+, PHPUnit 12 or Pest 4. Issues and pull requests on GitHub.