dvdoug/behat-code-coverage
Behat extension that generates code coverage reports for PHP applications. Wraps PHPUnit’s php-code-coverage library to produce familiar, interoperable reports and integrates coverage generation into your Behat test runs.
composer require --dev dvdoug/behat-code-coverage
behat.yml:
extensions:
LeanPHP\Behat\CodeCoverage\CodeCoverageExtension:
format: [clover, html]
output: ./build/coverage
./vendor/bin/behat --colors
Reports will be generated in ./build/coverage.Generate an HTML report to visualize test coverage in your Laravel application:
extensions:
LeanPHP\Behat\CodeCoverage\CodeCoverageExtension:
format: [html]
output: ./storage/logs/behat-coverage
html:
directory: ./storage/logs/behat-coverage/html
colors: true
Access the report at http://localhost/storage/logs/behat-coverage/html/index.html after running Behat.
CI/CD Pipeline:
- name: Run Behat with Coverage
run: ./vendor/bin/behat --config=behat.yml --no-interaction --colors
- name: Upload Coverage Report
uses: actions/upload-artifact@v3
with:
name: coverage-report
path: ./storage/logs/behat-coverage
php-coveralls/php-coveralls).Local Development:
--no-coverage for faster local runs:
./vendor/bin/behat --no-coverage
./vendor/bin/behat --config=behat-coverage.yml
Multi-Format Reports:
extensions:
LeanPHP\Behat\CodeCoverage\CodeCoverageExtension:
reports:
clover: ./storage/logs/clover.xml
html: ./storage/logs/html
cobertura: ./storage/logs/cobertura.xml
openclover: ./storage/logs/openclover.xml
Filtering Coverage:
extensions:
LeanPHP\Behat\CodeCoverage\CodeCoverageExtension:
filter:
include:
- app/Http/Controllers/
- app/Services/
exclude:
- app/Providers/*
- tests/*
output: ./storage/logs/coverage
Branch/Path Coverage (Xdebug required):
extensions:
LeanPHP\Behat\CodeCoverage\CodeCoverageExtension:
branchAndPathCoverage: true
output: ./storage/logs/branch-coverage
Artisan Integration: Create a custom Artisan command to run Behat with coverage:
// app/Console/Commands/RunBehatWithCoverage.php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Symfony\Component\Process\Process;
class RunBehatWithCoverage extends Command
{
protected $signature = 'behat:coverage';
protected $description = 'Run Behat tests with code coverage';
public function handle()
{
$process = new Process(['./vendor/bin/behat', '--config=behat.yml']);
$process->run();
$this->output->write($process->getOutput());
}
}
Run with:
php artisan behat:coverage
Storage Paths: Use Laravel’s storage paths for consistency:
extensions:
LeanPHP\Behat\CodeCoverage\CodeCoverageExtension:
output: ./storage/app/behat-coverage
Missing Coverage Drivers:
No coverage driver found.xdebug or pcov is installed and enabled:
pecl install xdebug
Add to php.ini:
zend_extension=xdebug.so
xdebug.mode=coverage
Path Issues:
storage_path() helper:
output: ./storage/app/behat-coverage
Or in PHP:
$config['output'] = storage_path('app/behat-coverage');
Xdebug Conflicts:
pcov and xdebug are enabled.xdebug.coverage_enable or use pcov exclusively:
xdebug.coverage_enable=0
Cache Issues:
rm -rf ./var/behat-code-coverage-cache
Or configure a custom cache path:
cache: ./storage/framework/cache/behat-coverage
Verbose Output:
Run Behat with -vvv to debug extension initialization:
./vendor/bin/behat -vvv
Check Configuration:
Validate your behat.yml using the --dry-run flag:
./vendor/bin/behat --dry-run
Report Validation:
Use tools like php-coveralls to validate report formats:
composer require --dev php-coveralls/php-coveralls
vendor/bin/coveralls --coverage_by_file --json_path=./storage/logs/clover.xml
Custom Report Formats:
Extend the package by adding new report formats. Example for json:
reports:
json: ./storage/logs/coverage.json
Ensure phpunit/php-code-coverage supports the format (check their docs).
Pre/Post-Test Hooks: Use Behat hooks to trigger coverage reports dynamically:
// features/bootstrap/FeatureContext.php
use LeanPHP\Behat\CodeCoverage\CodeCoverageExtension;
use Behat\Behat\Event\SuiteEvent;
$eventDispatcher->addListener(SuiteEvent::BEFORE_SUITE, function (SuiteEvent $event) {
$extension = $event->getSuite()->getEnvironment()->getExtension('code_coverage');
if ($extension instanceof CodeCoverageExtension) {
$extension->setOutput(storage_path('logs/behat-coverage-dynamic'));
}
});
CI-Specific Configs: Use environment variables to switch configurations:
# behat.yml
extensions:
LeanPHP\Behat\CodeCoverage\CodeCoverageExtension:
output: '%env(BEHAT_COVERAGE_OUTPUT, ./storage/logs/coverage)%'
Set in CI:
export BEHAT_COVERAGE_OUTPUT=./build/coverage
Service Provider Conflicts:
If using Laravel’s BehatTestCase, ensure the extension is loaded after Behat’s service provider:
// config/behat.php
'extensions' => [
LeanPHP\Behat\CodeCoverage\CodeCoverageExtension::class,
],
Storage Permissions: Ensure the coverage output directory is writable:
chmod -R 775 ./storage/logs
Docker Environments:
For Dockerized Laravel apps, ensure xdebug or pcov is installed in the container:
RUN pecl install xdebug && docker-php-ext-enable xdebug
How can I help you explore Laravel packages today?