Azvya Erstevan
Azvya Erstevan

Reputation: 154

Laravel: include folders in PHPUnit's Coverage-report (if outside of app/ folder)?

I have small problem here after refactoring my Laravel application to be modular when doing PHPUnit Coverage report.

This is my directory structure after refactoring:

laravel-project/
├── app/
│   ├── Exception
│   ├── Providers
│   └── ...
├── modules/
│   ├── ModuleA/
│   │   ├── Services
│   │   ├── Http/
│   │   │   ├── Controllers
│   │   │   └── Requests
│   │   └── Models
│   └── ModuleB/
│       └── ...
├── tests
└── ...

This is my phpunit xml configuration

<?xml version="1.0" encoding="UTF-8"?>
<phpunit 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:noNamespaceSchemaLocation="./vendor/phpunit/phpunit/phpunit.xsd" 
    bootstrap="vendor/autoload.php" 
    colors="true">

    <testsuites>
        <testsuite name="Unit">
            <directory suffix="Test.php">./tests/Unit</directory>
        </testsuite>
        <testsuite name="Feature">
            <directory suffix="Test.php">./tests/Feature</directory>
        </testsuite>
    </testsuites>
    <coverage processUncoveredFiles="true">
        <include>
            <directory suffix=".php">./app</directory>
            <directory suffix=".php">./modules</directory>
        </include>
        <exclude>
            <directory suffix=".php">./modules/*/database</directory>
        </exclude>
    </coverage>
    <php>
        <env name="APP_ENV" value="testing"/>
        <env name="APP_URL" value="https://nginx"/>
        <env name="DB_CONNECTION" value="sqlite"/>
        <env name="DB_DATABASE" value="/var/www/html/database/database.sqlite"/>
        <env name="CACHE_DRIVER" value="redis"/>
        <env name="MAIL_MAILER" value="array"/>
        <env name="QUEUE_CONNECTION" value="redis"/>
        <env name="SESSION_DRIVER" value="array"/>
        <env name="TELESCOPE_ENABLED" value="false"/>
    </php>
</phpunit>

The problem occurs when i try to do phpunit coverage report phpunit test --coverage command where there is no any modules folder being covered on the output:

Coverage report screenhsot

When I try to remove the processUncoveredFiles="true" options on the coverage filter, it shows the modules coverage BUT, every tests I've been created (even though it's calling methods inside modules folder), still it won't increase the coverage percentage of the modules coverage report.

Has anyone encounter this issue before when trying to include coverage/tests other than app/ folder of Laravel?

How To Include Folder outside app/ to Phpunit Coverage Report, e.g. Modules or Database folder which has same directory level as the app/ folder?

Upvotes: 2

Views: 1165

Answers (1)

Your Common Sense
Your Common Sense

Reputation: 34

It depends on PHPUnit version (sometime even Laravel versions).

Here is what works for me:

<filter>
    <whitelist processUncoveredFilesFromWhitelist="true">
        <directory suffix=".php">./app</directory>
        <directory suffix=".php">./modules</directory>
        <exclude>
            <directory suffix=".php">./modules/**/database</directory>
        </exclude>
    </whitelist>
</filter>

Try above instead of <coverage ...> tag, I mean, remove your:

<coverage processUncoveredFiles="true">
    <include>
        <directory suffix=".php">./app</directory>
        <directory suffix=".php">./modules</directory>
    </include>
    <exclude>
        <directory suffix=".php">./modules/*/database</directory>
    </exclude>
</coverage>

Example Command-line

To ensure the command is executed from right folder, without cd need, create test-coverage composer-script, like:

{

    // ...

    "scripts": {
        "test-coverage": [
            "Composer\\Config::disableProcessTimeout",
            "@php -d xdebug.mode=coverage vendor/phpunit/phpunit/phpunit --coverage-html ./.build/coverage --verbose"
        ]
    }
}

And execute it whenever required, like:

composer run test-coverage

Finally, see result in ./.build/coverage/index.html file.

Note that I prefer HTML report, and for that, I added my .build folder to .gitignore, but feel free to change above command.

Also, for Composer older than 1.9, remove "Composer\\Config::disableProcessTimeout", line, and instead try something like:

{
   "config": {
       "process-timeout": 0
   },
}

Upvotes: 1

Related Questions