Tangible Bytes

A Web Developer’s Blog

Laravel Docker Code Coverage

How to get code coverage reports from PHPUnit to Sonarqube

I started already having an environment using docker-compose but without xdebug the unit tests couldn’t generate coverage reports.

Docker

Add these lines in the build section of the Dockerfile

## Install xdebug
RUN pecl install xdebug  \
       && docker-php-ext-enable  xdebug

Rebuild the docker container and restart services

docker-compose build
docker-compose restart

Check Xdebug is enabled

docker-compose exec your_project_name  php -i

You should see a bunch of Xdebug info

Configure PHPUnit

I added these lines to my phpunit.xml file

This puts the reports in a folder phpunit_reports

It generates both the machine readable file for Sonarqube and also human readable html and text formats.

 <coverage processUncoveredFiles="true">
        <include>
            <directory suffix=".php">./app</directory>
        </include>
        <exclude>
            <directory>phpunit_reports</directory>
        </exclude>
        <report>
        <html outputDirectory="phpunit_reports/html-coverage" lowUpperBound="50" highLowerBound="90"/>
        <clover outputFile="phpunit_reports/coverage.xml" />
        </report>
    </coverage>
    <logging>
        <testdoxHtml outputFile="phpunit_reports/testdox.html"/>
        <testdoxText outputFile="phpunit_reports/testdox.txt"/>
        <junit outputFile="phpunit_reports/junit.xml"/>
        <text outputFile="phpunit_reports/logfile.txt"/>
    </logging>

Git Ignore

Make sure generated files don’t get committed

Add these lines to .gitignore

/phpunit_reports/
.scannerwork/

Run the Tests

docker-compose exec your_project_name php -dxdebug.mode=coverage ./vendor/bin/phpunit

Sonarqube

create a sonar-project.properties file like

sonar.projectKey=your_project_name
sonar.sources=app,bootstrap,config,lang,routes
sonar.tests=tests

I’m running the tests on docker but sonar_scanner locally and as a result I need to edit the report so that sonar find the paths as they are locally. You could run sonar-scanner on teh container instead.

sed -i 's|/var/www|.|' phpunit_reports/coverage.xml 
sonar-scanner -Dsonar.host.url=http://localhost:9000   -Dsonar.login=***yoursonarkey***

Shortly after the coverage reports show up in my local Sonarqube instance.

The process is fairly similar for running in a CI pipeline.