sebastianbergmann / phpcov

TextUI frontend for php-code-coverage
BSD 3-Clause "New" or "Revised" License
223 stars 58 forks source link

Class not found (custom autoloader) #101

Closed mrodikov closed 1 year ago

mrodikov commented 3 years ago
Q A
PHPUnit version 9.3.8
PHPCov version 8.1.0
PHP version 7.3.11, 7.4.7
Installation Method Composer

(PHAR doesn't work for me with the above PHPUnit & PHPCov versions, coverage file produced by PHPUnit is loaded as "Incomplete" class in PHPCov)

Summary

When using a custom class loader and processUncoveredFiles="true", an error occurs in PHPCov due to inability to find the class.

Current behavior

Generating code coverage report in HTML format ...
[Uncaught Error in /path/to/phpcov-issue-demo/lib/MyPreciousLib/Seasonings/TikkaMassala.php on line 3]
Error: Class 'BaseSeasonings_Curry' not found in /path/to/phpcov-issue-demo/lib/MyPreciousLib/Seasonings/TikkaMassala.php:3

How to reproduce

  1. Clone demo project https://github.com/mrodikov/phpcov-issue-demo
  2. phpdbg -qrr /path/to/any/phpunit/bin/phpunit -c /path/to/phpcov-issue-demo/lib/MyPreciousLib/phpunit.xml --coverage-php /path/to/phpcov-issue-demo/var/coverage.cov
  3. phpdbg -qrr /path/to/any/phpcov/bin/phpcov  merge --html /path/to/html/report/ /path/to/phpcov-issue-demo/var/

Expected behavior

HTML coverage report generated

Notes

The problem is that the custom autoloader is used, which can load Path_To_My_Real_Class classes from Path/To/My/Real/Class.php (obviously, the includePath option will not work here). PHPUnit uses a custom autoloader since I explicitly included it in bootstrap.php. PHPCov knows nothing about phpunit.xml or bootstrap.php, so it cannot find the class.

lex0r commented 2 years ago

It's been more than a year and still no feedback on this one. I have exactly same issue, but for me it may not happen for some tests I get coverage report for. I've been trying to understand the difference between the OK and failing coverages but still no luck.

lex0r commented 2 years ago

I managed to identify a more specific context for the error, when using phpcov's merge command. It seems the error is not related with the fact a "custom" autoloader is used, since I use the default composer's one.

Basically, if a file with a class is completely uncovered and when CodeCoverage::processUncoveredFilesFromFilter() takes care of including these, it just does include_once on the file. If a class defined in the file uses a trait, the trait inclusion will fail leading to "Fatal error: Trait 'Foo\Bar' not found in ...".

This might be caused by the fact that phpcov relies on its own spl_autoload_register() handler which has no knowledge of the user code base. When a trait is included by a class with "use Bar;" obviously it can't be found among the classes known to phpcov's autoloader.

@sebastianbergmann FYI

llupa commented 2 years ago

Had a similar experience. In my case I took a shortcut: added phpcov as a composer --dev dependency and afterwards all namespaces were resolved correctly.

swarrenwecareconnectorg commented 2 years ago

@llupa how did you add it through Composer?

llupa commented 2 years ago

@swarrenwecareconnectorg regular composer require --dev phpunit/phpcov and then call it via vendor/bin/phpcov merge [options and arguments]

Legion112 commented 1 year ago

Any update on this one? I have the same issue with the not found file.

/app # phpcov patch-coverage --path-prefix /app var/unit.cov var/patch.txt
phpcov 8.2.1 by Sebastian Bergmann.

Fatal error: Uncaught Error: Class "Symfony\Component\Console\Command\Command" not found in /app/src/Command/BackgroundTasksDaemonCommand.php:12
Stack trace:
#0 phar:///usr/local/bin/phpcov/phpunit/php-code-coverage/src/CodeCoverage.php(547): include_once()
#1 phar:///usr/local/bin/phpcov/phpunit/php-code-coverage/src/CodeCoverage.php(159): SebastianBergmann\CodeCoverage\CodeCoverage->processUncoveredFilesFromFilter()
#2 phar:///usr/local/bin/phpcov/src/PatchCoverage.php(39): SebastianBergmann\CodeCoverage\CodeCoverage->getData()
#3 phar:///usr/local/bin/phpcov/src/cli/PatchCoverageCommand.php(41): SebastianBergmann\PHPCOV\PatchCoverage->execute('var/unit.cov', 'var/patch.txt', '/app/')
#4 phar:///usr/local/bin/phpcov/src/cli/Application.php(51): SebastianBergmann\PHPCOV\PatchCoverageCommand->run(Object(SebastianBergmann\PHPCOV\Arguments))
#5 /usr/local/bin/phpcov(852): SebastianBergmann\PHPCOV\Application->run(Array)
#6 {main}
  thrown in /app/src/Command/BackgroundTasksDaemonCommand.php on line 12
sebastianbergmann commented 1 year ago

Superseded by #109, see https://github.com/sebastianbergmann/phpcov/issues/109#issuecomment-944345050.