O Sonda insere sondas no fonte antes de carregá-lo, como o Istanbul faz no JavaScript. A suíte roda no tempo normal dela, e cada decisão precisa mostrar os dois desfechos.
Uma aplicação Laravel 13 com Filament, Pest 4 e Postgres: 4.514 testes, medidos na mesma máquina. O Xdebug com path coverage não terminou em uma hora.
Memória: 308 MB sem cobertura, 317 MB com o Sonda, 640 MB com o Xdebug só de linhas. Com ParaTest e 10 workers: 42 s sem cobertura, 40 s com o Sonda.
Feito para ser trava de merge: 100% das linhas e dos branches do que o merge request mudou, no tempo que a suíte já leva.
Cada desfecho de if, laços, match, ?:, ??, ?-> e dos operadores de curto-circuito é um branch com a própria sonda.
Nada para instalar no runner. Qualquer PHP 8.4+ com o seu vendor/ basta; o relatório sai do php-code-coverage.
Um if sem else ainda precisa dos dois desfechos testados. O Sonda sintetiza o else e o conta.
--changed mede os arquivos que o seu branch tocou e falha se uma linha ou branch deles ficar descoberta.
--affected roda só os testes que executaram os arquivos mudados, por um mapa que a execução anterior gravou.
Os templates compilados são instrumentados e mapeados de volta para a view, linha e branch, diretivas próprias incluídas.
Sem interceptar opcodes e sem enumerar caminhos, que é o que deixa o Xdebug lento. Uma sonda é uma atribuição num array, e a cópia instrumentada preserva todas as linhas.
Cada arquivo do source do seu phpunit.xml ganha uma sonda em cada desfecho de branch. As cópias ficam em cache por hash do arquivo: a segunda execução não instrumenta nada.
Um bootstrap registra um autoloader antes do do Composer, que carrega as cópias. PHPUnit, Pest, ParaTest e artisan test rodam como sempre; cada worker grava o que executou.
As sondas viram um relatório do php-code-coverage: HTML, Clover, Cobertura para o diff do GitLab e Code Quality apontando as linhas descobertas.
public function total(): int
{
if ($this->items === []) {
return 0;
}
return $this->sum() + $this->shipping;
}
public function total(): int
{
$h = &Hits::$current['a1b2c3'];
$h[1] = 1;
if ($this->items === []) {
$h[2] = 1;
return 0;
} else { $h[3] = 1; }
$h[4] = 1;
return $this->sum() + $this->shipping;
}
Composer, depois sonda test na raiz do projeto. PHP 8.4+, PHPUnit 12 ou Pest 4.
Ler o guia de início