PhpMetrics
PhpMetrics copied to clipboard
My JUnit's xml didn't showing up on PhpMetrics reports.
Hi,
I've installed PhpMetrics v2.0.0 as phar archive (under docker image).
When I run this command:
phpmetrics --report-html=build/metrics --junit=build/coverage/report.xml src
I get this output:
LOC
Lines of code 354
Logical lines of code 222
Comment lines of code 132
Average volume 60.16
Average comment weight 31.38
Average intelligent content 31.38
Logical lines of code by class 19
Logical lines of code by method 11
Object oriented programming
Classes 12
Interface 0
Methods 21
Methods by class 1.75
Lack of cohesion of methods 1.31
Average afferent coupling 0.54
Average efferent coupling 3.46
Average instability 0.75
Complexity
Average Cyclomatic complexity by class 1.54
Average Relative system complexity 10.16
Average Difficulty 1.95
Bugs
Average bugs by class 0.02
Average defects by class (Kan) 0.19
Violations
Critical 0
Error 0
Warning 0
Information 0
Unit testing
Number of unit tests 0
Classes called by tests 0
Classes called by tests (percent) 0 %
HTML report generated in "build/metrics" directory
And I expected this to happen:
Unit testing
Number of unit tests 20
Classes called by tests 7
Classes called by tests (percent) 70 %
Looks like phpmetrics
didn't parse my build/coverage/report.xml
at all.
It doesn't throw something like parse error or file not found error at all, but the result is all 0.
My report.xml
are generated by Codeception, and this is how it looks like
<?xml version="1.0" encoding="UTF-8"?>
<testsuites>
<testsuite name="MyProject.unit" tests="20" assertions="27" failures="0" errors="0" time="0.325358">
<testcase name="testGetNewToken" class="MyProject\AccessToken\Repository\MongoDbAccessTokenRepositoryTest" file="/project/tests/unit/AccessToken/Repository/MongoDbAccessTokenRepositoryTest.php" assertions="1" time="0.039714"/>
<testcase name="testRevokeAccessToken" class="MyProject\AccessToken\Repository\MongoDbAccessTokenRepositoryTest" file="/project/tests/unit/AccessToken/Repository/MongoDbAccessTokenRepositoryTest.php" assertions="1" time="0.028355"/>
<testcase name="testIsAccessTokenRevoked with data set #0" class="MyProject\AccessToken\Repository\MongoDbAccessTokenRepositoryTest" file="/project/tests/unit/AccessToken/Repository/MongoDbAccessTokenRepositoryTest.php" assertions="1" time="0.019613"/>
<testcase name="testIsAccessTokenRevoked with data set #1" class="MyProject\AccessToken\Repository\MongoDbAccessTokenRepositoryTest" file="/project/tests/unit/AccessToken/Repository/MongoDbAccessTokenRepositoryTest.php" assertions="1" time="0.034427"/>
<testcase name="testGetClientEntity" class="MyProject\Client\Repository\PhpArrayClientRepositoryTest" file="/project/tests/unit/Client/Repository/PhpArrayClientRepositoryTest.php" assertions="4" time="0.005750"/>
<testcase name="testGetClientEntityWithoutValidatingSecret" class="MyProject\Client\Repository\PhpArrayClientRepositoryTest" file="/project/tests/unit/Client/Repository/PhpArrayClientRepositoryTest.php" assertions="3" time="0.004221"/>
<testcase name="testGetClientEntityWithUnknownIdentifier" class="MyProject\Client\Repository\PhpArrayClientRepositoryTest" file="/project/tests/unit/Client/Repository/PhpArrayClientRepositoryTest.php" assertions="1" time="0.004617"/>
<testcase name="testGetClientEntityWithNotAllowedGrantType" class="MyProject\Client\Repository\PhpArrayClientRepositoryTest" file="/project/tests/unit/Client/Repository/PhpArrayClientRepositoryTest.php" assertions="1" time="0.003887"/>
<testcase name="testGetClientEntityWithInvalidClientSecret" class="MyProject\Client\Repository\PhpArrayClientRepositoryTest" file="/project/tests/unit/Client/Repository/PhpArrayClientRepositoryTest.php" assertions="1" time="0.004902"/>
<testcase name="testGetNewRefreshToken" class="MyProject\RefreshToken\Repository\MongoDbRefreshTokenRepositoryTest" file="/project/tests/unit/RefreshToken/Repository/MongoDbRefreshTokenRepositoryTest.php" assertions="1" time="0.006503"/>
<testcase name="testRevokeRefreshToken" class="MyProject\RefreshToken\Repository\MongoDbRefreshTokenRepositoryTest" file="/project/tests/unit/RefreshToken/Repository/MongoDbRefreshTokenRepositoryTest.php" assertions="1" time="0.026962"/>
<testcase name="testIsRefreshTokenRevoked with data set #0" class="MyProject\RefreshToken\Repository\MongoDbRefreshTokenRepositoryTest" file="/project/tests/unit/RefreshToken/Repository/MongoDbRefreshTokenRepositoryTest.php" assertions="1" time="0.022090"/>
<testcase name="testIsRefreshTokenRevoked with data set #1" class="MyProject\RefreshToken\Repository\MongoDbRefreshTokenRepositoryTest" file="/project/tests/unit/RefreshToken/Repository/MongoDbRefreshTokenRepositoryTest.php" assertions="1" time="0.031927"/>
<testcase name="testGetScopeEntityByIdentifier" class="MyProject\Scope\Repository\PhpArrayScopeRepositoryTest" file="/project/tests/unit/Scope/Repository/PhpArrayScopeRepositoryTest.php" assertions="1" time="0.006284"/>
<testcase name="testFinalizeScopes" class="MyProject\Scope\Repository\PhpArrayScopeRepositoryTest" file="/project/tests/unit/Scope/Repository/PhpArrayScopeRepositoryTest.php" assertions="1" time="0.003820"/>
<testcase name="testGetUserEntityByUserCredentials" class="MyProject\User\Repository\PhpArrayUserRepositoryTest" file="/project/tests/unit/User/Repository/PhpArrayUserRepositoryTest.php" assertions="2" time="0.012517"/>
<testcase name="testGetUserEntityByUserCredentialsWithWrongCredentials with data set #0" class="MyProject\User\Repository\PhpArrayUserRepositoryTest" file="/project/tests/unit/User/Repository/PhpArrayUserRepositoryTest.php" assertions="1" time="0.011311"/>
<testcase name="testGetUserEntityByUserCredentialsWithWrongCredentials with data set #1" class="MyProject\User\Repository\PhpArrayUserRepositoryTest" file="/project/tests/unit/User/Repository/PhpArrayUserRepositoryTest.php" assertions="1" time="0.013324"/>
<testcase name="testGetUserEntityByUserCredentials" class="MyProject\User\Repository\ServiceUserRepositoryTest" file="/project/tests/unit/User/Repository/ServiceUserRepositoryTest.php" assertions="2" time="0.025776"/>
<testcase name="testGetUserEntityByUserCredentialsWithWrongCredentials" class="MyProject\User\Repository\ServiceUserRepositoryTest" file="/project/tests/unit/User/Repository/ServiceUserRepositoryTest.php" assertions="1" time="0.019359"/>
</testsuite>
</testsuites>
I would love to know why this happens?
If my report.xml
is not in the right format, maybe phpmetrics should throw some parse error message.
Or maybe some --verbose
flag would help me understand.
Thanks
Can you retry with the latest PhpMetrics version please ?
Trying it on 2.1.0
, looks like it works fine now.
Thanks
Hi,
why did you reopened this issue ? Does the bug continues to occur ?
Ugh, i clicked the wrong button when submitting my comment, then re-open it.
Sorry.
But on some of my project, i got this error.
> phpmetrics --report-html=build/metrics --junit=build/coverage/report.xml src
... 100% ...
Fatal error: Uncaught Error: Call to a member function toString() on null in phar:///usr/local/bin/phpmetrics/src/Hal/Metric/Class_/Coupling/ExternalsVisitor.php:55
Stack trace:
#0 phar:///usr/local/bin/phpmetrics/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php(127): Hal\Metric\Class_\Coupling\ExternalsVisitor->leaveNode(Object(PhpParser\Node\Stmt\Class_))
#1 phar:///usr/local/bin/phpmetrics/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php(120): PhpParser\NodeTraverser->traverseNode(Object(PhpParser\Node\Expr\New_))
#2 phar:///usr/local/bin/phpmetrics/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php(171): PhpParser\NodeTraverser->traverseNode(Object(PhpParser\Node\Expr\Assign))
#3 phar:///usr/local/bin/phpmetrics/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php(101): PhpParser\NodeTraverser->traverseArray(Array)
#4 phar:///usr/local/bin/phpmetrics/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php(171): PhpParser\NodeTraverser->traverseNode(Object(PhpParser\Node\Stmt\ClassMethod))
#5 phar in phar:///usr/local/bin/phpmetrics/src/Hal/Metric/Class_/Coupling/ExternalsVisitor.php on line 55
Here is the junit xml that throws that error
<?xml version="1.0" encoding="UTF-8"?>
<testsuites>
<testsuite name="MyProject.unit" tests="60" assertions="138" failures="0" errors="0" time="1.186054">
<testcase name="testSilentSignIn" class="MyProject\Command\SilentSignInUsingGoogleCommandHandlerTest" file="/project/tests/unit/Command/SilentSignInUsingGoogleCommandHandlerTest.php" assertions="0" time="0.430190"/>
<testcase name="testRegistration" class="MyProject\Command\UpdateUserUsingGoogleCommandHandlerTest" file="/project/tests/unit/Command/UpdateUserUsingGoogleCommandHandlerTest.php" assertions="0" time="0.277143"/>
<testcase name="testUpdate" class="MyProject\Command\UpdateUserUsingGoogleCommandHandlerTest" file="/project/tests/unit/Command/UpdateUserUsingGoogleCommandHandlerTest.php" assertions="0" time="0.024767"/>
<testcase name="testUsingValidString with data set #0" class="MyProject\CountryIdTest" file="/project/tests/unit/CountryIdTest.php" assertions="1" time="0.017224"/>
<testcase name="testUsingValidString with data set #1" class="MyProject\CountryIdTest" file="/project/tests/unit/CountryIdTest.php" assertions="1" time="0.004079"/>
<testcase name="testUsingValidString with data set #2" class="MyProject\CountryIdTest" file="/project/tests/unit/CountryIdTest.php" assertions="1" time="0.004074"/>
<testcase name="testUsingInvalidString with data set #0" class="MyProject\CountryIdTest" file="/project/tests/unit/CountryIdTest.php" assertions="1" time="0.032285"/>
<testcase name="testUsingInvalidString with data set #1" class="MyProject\CountryIdTest" file="/project/tests/unit/CountryIdTest.php" assertions="1" time="0.004229"/>
<testcase name="testUsingInvalidString with data set #2" class="MyProject\CountryIdTest" file="/project/tests/unit/CountryIdTest.php" assertions="1" time="0.004206"/>
<testcase name="testUsingInvalidString with data set #3" class="MyProject\CountryIdTest" file="/project/tests/unit/CountryIdTest.php" assertions="1" time="0.004082"/>
<testcase name="testUsingInvalidString with data set #4" class="MyProject\CountryIdTest" file="/project/tests/unit/CountryIdTest.php" assertions="1" time="0.004094"/>
<testcase name="testUsingInvalidString with data set #5" class="MyProject\CountryIdTest" file="/project/tests/unit/CountryIdTest.php" assertions="1" time="0.004536"/>
<testcase name="testUsingInvalidString with data set #6" class="MyProject\CountryIdTest" file="/project/tests/unit/CountryIdTest.php" assertions="1" time="0.004340"/>
<testcase name="testConstructorThrowsError" class="MyProject\CountryTest" file="/project/tests/unit/CountryTest.php" assertions="1" time="0.003514"/>
<testcase name="testCreation" class="MyProject\CountryTest" file="/project/tests/unit/CountryTest.php" assertions="2" time="0.048465"/>
<testcase name="testDefaultMessage" class="MyProject\DataSourceExceptionTest" file="/project/tests/unit/DataSourceExceptionTest.php" assertions="1" time="0.010315"/>
<testcase name="testUsingValidString with data set #0" class="MyProject\EmailTest" file="/project/tests/unit/EmailTest.php" assertions="4" time="0.004789"/>
<testcase name="testUsingInvalidString with data set #0" class="MyProject\EmailTest" file="/project/tests/unit/EmailTest.php" assertions="1" time="0.003824"/>
<testcase name="testUsingInvalidString with data set #1" class="MyProject\EmailTest" file="/project/tests/unit/EmailTest.php" assertions="1" time="0.003869"/>
<testcase name="testUsingInvalidString with data set #2" class="MyProject\EmailTest" file="/project/tests/unit/EmailTest.php" assertions="1" time="0.003952"/>
<testcase name="testUsingInvalidString with data set #3" class="MyProject\EmailTest" file="/project/tests/unit/EmailTest.php" assertions="1" time="0.003852"/>
<testcase name="testUsingInvalidString with data set #4" class="MyProject\EmailTest" file="/project/tests/unit/EmailTest.php" assertions="1" time="0.003893"/>
<testcase name="testUsingInvalidString with data set #5" class="MyProject\EmailTest" file="/project/tests/unit/EmailTest.php" assertions="1" time="0.003881"/>
<testcase name="testDefaultMessage" class="MyProject\EntityNotFoundExceptionTest" file="/project/tests/unit/EntityNotFoundExceptionTest.php" assertions="1" time="0.003947"/>
<testcase name="testCreation" class="MyProject\Event\UserUpdatedTest" file="/project/tests/unit/Event/UserUpdatedTest.php" assertions="1" time="0.004505"/>
<testcase name="testCreation" class="MyProject\EventTest" file="/project/tests/unit/EventTest.php" assertions="4" time="0.005280"/>
<testcase name="testCreationWithMinimal" class="MyProject\Field\TextFieldHasDefaultTest" file="/project/tests/unit/Field/TextFieldHasDefaultTest.php" assertions="8" time="0.043979"/>
<testcase name="testCreation" class="MyProject\Field\TextFieldHasDefaultTest" file="/project/tests/unit/Field/TextFieldHasDefaultTest.php" assertions="10" time="0.008073"/>
<testcase name="testCreationWithInvalidParams with data set #0" class="MyProject\Field\TextFieldHasDefaultTest" file="/project/tests/unit/Field/TextFieldHasDefaultTest.php" assertions="1" time="0.006387"/>
<testcase name="testCreationWithInvalidParams with data set #1" class="MyProject\Field\TextFieldHasDefaultTest" file="/project/tests/unit/Field/TextFieldHasDefaultTest.php" assertions="1" time="0.006175"/>
<testcase name="testCreationWithMinimal" class="MyProject\FieldTest" file="/project/tests/unit/FieldTest.php" assertions="7" time="0.006265"/>
<testcase name="testCreation" class="MyProject\FieldTest" file="/project/tests/unit/FieldTest.php" assertions="8" time="0.006833"/>
<testcase name="testCreationWithInvalidParams with data set #0" class="MyProject\FieldTest" file="/project/tests/unit/FieldTest.php" assertions="1" time="0.005555"/>
<testcase name="testCreationWithInvalidParams with data set #1" class="MyProject\FieldTest" file="/project/tests/unit/FieldTest.php" assertions="1" time="0.005380"/>
<testcase name="testCreationWithInvalidParams with data set #2" class="MyProject\FieldTest" file="/project/tests/unit/FieldTest.php" assertions="1" time="0.006127"/>
<testcase name="testCreationWithInvalidParams with data set #3" class="MyProject\FieldTest" file="/project/tests/unit/FieldTest.php" assertions="1" time="0.005941"/>
<testcase name="testCreationWithInvalidParams with data set #4" class="MyProject\FieldTest" file="/project/tests/unit/FieldTest.php" assertions="1" time="0.006139"/>
<testcase name="testFromData" class="MyProject\GoogleUserTest" file="/project/tests/unit/GoogleUserTest.php" assertions="9" time="0.005765"/>
<testcase name="testFromDataWithEmptyValues" class="MyProject\GoogleUserTest" file="/project/tests/unit/GoogleUserTest.php" assertions="2" time="0.004587"/>
<testcase name="testFromDataWithExpired with data set #0" class="MyProject\GoogleUserTest" file="/project/tests/unit/GoogleUserTest.php" assertions="1" time="0.003826"/>
<testcase name="testFromDataWithExpired with data set #1" class="MyProject\GoogleUserTest" file="/project/tests/unit/GoogleUserTest.php" assertions="1" time="0.003836"/>
<testcase name="testFromDataWithExpired with data set #2" class="MyProject\GoogleUserTest" file="/project/tests/unit/GoogleUserTest.php" assertions="1" time="0.004096"/>
<testcase name="testEquals" class="MyProject\Identifier\AbstractIdentifierTest" file="/project/tests/unit/Identifier/AbstractIdentifierTest.php" assertions="2" time="0.004354"/>
<testcase name="testNotEquals" class="MyProject\Identifier\AbstractIdentifierTest" file="/project/tests/unit/Identifier/AbstractIdentifierTest.php" assertions="2" time="0.004271"/>
<testcase name="testFromValidString with data set #0" class="MyProject\Identifier\StringIdentifierTest" file="/project/tests/unit/Identifier/StringIdentifierTest.php" assertions="4" time="0.004634"/>
<testcase name="testFromValidString with data set #1" class="MyProject\Identifier\StringIdentifierTest" file="/project/tests/unit/Identifier/StringIdentifierTest.php" assertions="4" time="0.004712"/>
<testcase name="testFromInvalidString with data set #0" class="MyProject\Identifier\StringIdentifierTest" file="/project/tests/unit/Identifier/StringIdentifierTest.php" assertions="1" time="0.004905"/>
<testcase name="testFromInvalidString with data set #1" class="MyProject\Identifier\StringIdentifierTest" file="/project/tests/unit/Identifier/StringIdentifierTest.php" assertions="1" time="0.005319"/>
<testcase name="testFromValidString with data set #0" class="MyProject\Identifier\UuidIdentifierTest" file="/project/tests/unit/Identifier/UuidIdentifierTest.php" assertions="4" time="0.004989"/>
<testcase name="testFromValidString with data set #1" class="MyProject\Identifier\UuidIdentifierTest" file="/project/tests/unit/Identifier/UuidIdentifierTest.php" assertions="4" time="0.005391"/>
<testcase name="testFromInvalidString with data set #0" class="MyProject\Identifier\UuidIdentifierTest" file="/project/tests/unit/Identifier/UuidIdentifierTest.php" assertions="1" time="0.003978"/>
<testcase name="testFromInvalidString with data set #1" class="MyProject\Identifier\UuidIdentifierTest" file="/project/tests/unit/Identifier/UuidIdentifierTest.php" assertions="1" time="0.004808"/>
<testcase name="testFromInvalidString with data set #2" class="MyProject\Identifier\UuidIdentifierTest" file="/project/tests/unit/Identifier/UuidIdentifierTest.php" assertions="1" time="0.005221"/>
<testcase name="testFromInvalidString with data set #3" class="MyProject\Identifier\UuidIdentifierTest" file="/project/tests/unit/Identifier/UuidIdentifierTest.php" assertions="1" time="0.004000"/>
<testcase name="testGenerate" class="MyProject\Identifier\UuidIdentifierTest" file="/project/tests/unit/Identifier/UuidIdentifierTest.php" assertions="1" time="0.004329"/>
<testcase name="testGetter" class="MyProject\PlatformTest" file="/project/tests/unit/PlatformTest.php" assertions="2" time="0.005399"/>
<testcase name="testCreation" class="MyProject\SilentSignInUserTest" file="/project/tests/unit/SilentSignInUserTest.php" assertions="1" time="0.003998"/>
<testcase name="testMarkAsSignedIn" class="MyProject\SilentSignInUserTest" file="/project/tests/unit/SilentSignInUserTest.php" assertions="4" time="0.007041"/>
<testcase name="testRegisterUsingGoogle" class="MyProject\UserTest" file="/project/tests/unit/UserTest.php" assertions="18" time="0.029589"/>
<testcase name="testUpdateProfileUsingGoogle" class="MyProject\UserTest" file="/project/tests/unit/UserTest.php" assertions="2" time="0.030817"/>
</testsuite>
</testsuites>
It works fine on some project, and throwing that error on some other project.
This will be fixed in the new release, but results of metrics based on phpunit will be false (set to 0). @Halleck45 I need some PR to be validated first before working on that point.
@niconoe- I do not understand why "results of metrics based on phpunit will be false"
Yeah, me too, it seems some variable must not be set correctly since the addition of the Codeception parsing, or something like that, I haven't the time to analyse more yesterday.
I'll work on it today (I hope I'll have time to), and find why.
Not the same trouble, but related: the absolute file names present in the junit reports are based upon the tool phpunit the client run. This base can be different from the base of the phpmetrics.
In my case, for example, I run phpunit
in a container mounting my sources in :/data/www/
folder.
I run phpmetrics
using the new docker image that requires me to mount my sources into :/app
folder.
So, the jUnit parsing of phpmetrics fails because it's seeking for files located in /data/www
while I'm into /app
.
I would suggest to base on the relative path defined in the first tag <testsuite>
, but finding the files in this tests suites requires to use the FQN classname assuming the project is following PSR-4, which is not always the case... So, I don't know how to proceed here.
I'll still try to manually replace the paths in my file in order to continue and fix this issue in particular, but the path definition might be a real problem in the future.
After all, it seems to work except for an output issue in the Cli Reporter. I was just testing it on a project containing only Traits and the PR about analysing traits is not merged yet...
I'm not sure about the results displayed on the generated site, but at least there are no more PHP errors. Improvements of the exactitude of the values can be done in another PR for another release (2.3.1 ?) IMO.
Also by taking into account my last comment, I think we can release a PHP error fixed first, then going further into this jUnit analysis.
@Halleck45 If you're OK with this, you can accept the PR #312 and we will be almost ready for the 2.3.0 release.
@herloct The release 2.3.0 has just come. Can you try it out to see if this issue is fixed now? Thanks a lot.
Fixed since v2.3.0.