PhpMetrics icon indicating copy to clipboard operation
PhpMetrics copied to clipboard

My JUnit's xml didn't showing up on PhpMetrics reports.

Open herloct opened this issue 7 years ago • 10 comments

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

herloct avatar Mar 05 '17 06:03 herloct

Can you retry with the latest PhpMetrics version please ?

Halleck45 avatar Apr 10 '17 11:04 Halleck45

Trying it on 2.1.0, looks like it works fine now.

Thanks

herloct avatar Apr 12 '17 11:04 herloct

Hi,

why did you reopened this issue ? Does the bug continues to occur ?

Halleck45 avatar Apr 12 '17 13:04 Halleck45

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.

herloct avatar Apr 12 '17 14:04 herloct

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- avatar Sep 19 '17 18:09 niconoe-

@niconoe- I do not understand why "results of metrics based on phpunit will be false"

Halleck45 avatar Sep 20 '17 05:09 Halleck45

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.

niconoe- avatar Sep 20 '17 12:09 niconoe-

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.

niconoe- avatar Sep 20 '17 16:09 niconoe-

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.

niconoe- avatar Sep 20 '17 17:09 niconoe-

@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.

niconoe- avatar Sep 22 '17 09:09 niconoe-

Fixed since v2.3.0.

niconoe- avatar Sep 22 '23 06:09 niconoe-