Sonda 1.16: branch coverage for PHP without Xdebug, now in English
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.
