I set up PHPUnit to work with two different namespaces in a non-Laravel project, and it works perfectly. This is the folder structure of my working example:
├── docker-compose.yml
├── Dockerfile
├── composer.json
├── phpunit.xml
├── app/
│ └── Example.php
├── modules/
│ └── Example.php
└── tests/
├── AppTest.php
└── ModulesTest.php
In this setup, phpunit.xml looks like this:
<testsuites>
<testsuite name="Tests">
<directory>tests</directory>
</testsuite>
</testsuites>
<source>
<include>
<directory>app</directory>
<directory>modules</directory>
</include>
</source>
And the namespaces are defined in composer.json as follows:
"autoload": {
"psr-4": {
"App\": "app/",
"Modules\": "modules/"
}
}
I run the following command to generate the coverage report:
docker compose exec php ./vendor/bin/phpunit --coverage-html coverage-report
In this non-Laravel example, the code coverage report correctly shows both app and modules namespaces covered by tests.
You can checkout the full repository of my example at https://github.com/iwasherefirst2/poc-coverage
The Issue in Laravel:
When I replicate this setup in a fresh Laravel 10.48.24 project, with the same structure and configuration, the coverage report fails to include the modules folder, even though the tests for it pass successfully.
Here is the Laravel-specific information:
- Laravel Version: 10.48.24
- PHP Version: 8.2.26
- PHPUnit Version: 10.x (same in both projects)
Both projects use the same PHPUnit version, and the tests in Laravel are plain unit tests (use PHPUnitFrameworkTestCase). However, the coverage report for my Laravel app only includes the app namespace, completely omitting modules.
Here is also the full repository to look at https://github.com/iwasherefirst2/poc-laravel-coverage-modules
What I Tried:
- Ensured the namespace configuration in composer.json is correct and ran composer dump-autoload.
- Used the same phpunit.xml structure in both projects.
- Verified that tests for the modules folder run successfully in Laravel.
Key Observations:
- The Laravel project is identical to the working example, except for the additional Laravel-specific files and dependencies.
- Despite this, the coverage report excludes the modules namespace in my Laravel app, but not in my simple php app.
Question:
Why does the PHPUnit code coverage report fail to include the modules namespace in Laravel, even though the tests are running and passing? Could this be related to Laravel’s PHPUnit integration or autoload configuration? How can I resolve this and ensure full coverage for both namespaces in Laravel?

