Swader
Swader

Reputation: 11597

PHPUnit code coverage for abstract class at 0% even though it's clearly tested

Writing a PHP package here, TDD with PhpUnit 4+.

Writing tests for all my regular classes works fine, and they're covered in the report. But when I test the mock of an abstract class, even though the test clearly runs through the method (it fails if I fail to implement it, or if I put some breakpoints in there), the code coverage is 0%.

I've extracted the offending code into a repo here, if you'd like to give it a whirl. All you need to do is clone, composer install, and run phpunit, it's all configured.

This is being run on a Vagrant box, so an isolated environment that has nothing in particular to do with my PHP version or available extensions, and was tested by other people, too, on their installations, producing the same results.

The abstract class being tested is here, while its test can be seen here.

Any hints on what I may be doing wrong here would be greatly appreciated.

Edit:

Okay, so, as an added explanation, see comments on the accepted answer below, and Jordi's tweets here. Basically, for perf reasons, Composer's autoloader just follows the case of the filesystem it's on, so it's best if one uses the same case on the folders as in the class names. If your namespace is uppercase, your folder should be, too. This still leaves open the question about why it actually managed to read and run the class' method, but didn't mark it as covered, so if you have any insight into that, please leave a comment or a more complete answer, and I'll re-accept that one.

Edit 2:

Additional sensible explanation by dstockto from IRC:

I believe the issue is because when phpunit is collecting the code coverage information, it's in PHP arrays. The keys are case sensitive and so even though you have covered that, the coverage was for a differently cased file which PHPunit doesn't match up to the files that were loaded

Upvotes: 1

Views: 916

Answers (1)

ragol
ragol

Reputation: 546

I've got it to work and Coverage is 100%. :-) The problem was this:

$ phpunit --verbose --bootstrap vendor/autoload.php
PHPUnit 4.4.2 by Sebastian Bergmann.

Configuration read from /home/ren/tmp/phpunit-oddity/phpunit.xml.dist

E

Time: 151 ms, Memory: 3.25Mb

There was 1 error:

1) Swader\Diffbot\Test\ApiTest::testSetTimeout
PHPUnit_Framework_MockObject_RuntimeException: Class "Swader\Diffbot\Abstracts\Api" does not exist.

Debugging has shown that the real problem is the case-insensitive filesystem on your host. Vagrant runs Linux. Directory abstracts is not the same as Abstracts. PhpUnit on Linux cannot find the class it's looking for.

Upvotes: 2

Related Questions