Skip to content

Conversation

@GhostLyrics
Copy link

This PR improves on the existing Junit report by implementing further attributes of the spec. I have attached samples of the output as well as examples how the results are parsed by a consumer, in this case GitLab.

  • classname and file are added to testcase elements
  • a generic "PHP_CodeSniffer" string is now used instead of the file name if all tests passed
  • Indention of the generated XML is now consistent.

  • I have run the CS checker and fixed all issues.
  • I have not run the phpunit test because no tests cover generating Junit reports as far as I saw.
  • I have tried implementing this as a custom report before, but I could not find a way to do both print a custom report to a file AND print a builtin report to stdout at the same time, so I sent this PR (The builtin report would also end up in my --report-file).

examples:

<!--BEFORE: inconsistently indented fragment of report.xml -->

<?xml version="1.0" encoding="UTF-8"?>
<testsuites name="PHP_CodeSniffer 3.5.4" errors="0" tests="104" failures="1">
<testsuite name="tests/unit/MiscUtilTest.php" errors="0" tests="1" failures="0">
    <testcase name="tests/unit/MiscUtilTest.php"/>
</testsuite>
[...]
<!-- AFTER: consistently indented fragment of report.xml -->

<?xml version="1.0" encoding="UTF-8"?>
<testsuites name="PHP_CodeSniffer 3.5.4" errors="0" tests="104" failures="1">
  <testsuite name="tests/unit/MiscUtilTest.php" errors="0" tests="1" failures="0">
    <testcase name="tests/unit/MiscUtilTest.php"/>
  </testsuite>
[...]
<!-- BEFORE: all information is contained only in "name" -->
<!-- line breaks added for readability of PR -->
<testcase name="PSR2.Methods.FunctionCallSignature.SpaceAfterOpenBracket at tests/unit/DeploymentCommandsTest.php (44:35)">
  <failure type="error" 
           message="Space after opening parenthesis of function call prohibited"/>
</testcase>
<!-- AFTER: information goes into their relevant attributes -->
<!-- line breaks added for readability of PR-->
<testcase classname="DeploymentCommandsTest" 
          file="tests/unit/DeploymentCommandsTest.php" 
          name="PSR2.Methods.FunctionCallSignature.SpaceAfterOpenBracket (44:35)">
  <failure type="error" 
           message="Space after opening parenthesis of function call prohibited (line 44, column 35)"/>
</testcase>

Before:
01-tests-tab-before
After:
01-tests-tab-after

+ use a generic PHP_CodeSniffer string as name in <testcase> if all sniffs passed
+ use the filename without extension as classname in <testcase>
+ move the full filepath from name to file in <testcase>
+ append line and column to message in <failure>
@GhostLyrics GhostLyrics marked this pull request as ready for review May 16, 2020 21:12
echo $cachedData;
echo '</testsuites>'.PHP_EOL;

$dom = new \DOMDocument();
Copy link
Contributor

@jrfnl jrfnl May 17, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please be aware that the DOM extension can be disabled, so may not be available and is currently not a requirement for PHPCS.

The XMLWriter extension and the SimpleXML extension are requirements, so please consider if it's possible to use those instead.

Refs:

  • "require": {
    "php": ">=5.4.0",
    "ext-tokenizer": "*",
    "ext-xmlwriter": "*",
    "ext-simplexml": "*"
  • $requiredExtensions = [
    'tokenizer',
    'xmlwriter',
    'SimpleXML',
    ];
    $missingExtensions = [];
    foreach ($requiredExtensions as $extension) {
    if (extension_loaded($extension) === false) {
    $missingExtensions[] = $extension;
    }
    }

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please be aware that the DOM extension can be disabled, so may not be available and is currently not a requirement for PHPCS.

I see. This is my first time writing PHP, so I assumed everything that's on PHP.net is shipped as default.

The XMLWriter extension and the SimpleXML extension are requirements, so please consider if it's possible to use those instead.

That depends on whether you consider consistent indentation important or not.

  • If indentation doesn't matter, then all the changes in generate() can be dropped.
  • Otherwise, I looked through the docs for XMLWriter and SimpleXML several times but did not find ways to work with the partial XML that's emitted by generateFileReport(). I couldn't figure out if implementing the echo within this function is essential or if I could just create a class member of Junit holding the XMLWriter, append content to that during calls of generateFileReport() and echo all of it at the end of generate(). That would also ensure consistent indentation and likely not require DOM.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is my first time writing PHP

Oh wow, respect for taking something like this on straight off the bat in that case 👍

if I could just create a class member of Junit holding the XMLWriter, append content to that during calls of generateFileReport() and echo all of it at the end of generate()

If I remember correctly, the echo in generateFileReport() is needed with how things are set up in PHPCS now, but this may be a legacy from PHP 4 when PHP didn't have a proper object model. (this project is quite old).
The downside of saving it to a class property instead of to a file, would be the memory this would consume, which could be extensive on a large project with lots of violations.

I suppose you could just save the minimum information you need from each file in non-XML format, like is done for the Summary report, and then use the generate() method to parse the saved information and format it the way you want it to be.
Will be less efficient as the data is processed twice, but could possibly get you closer to the intended result.

@GhostLyrics
Copy link
Author

Seeing as this has been open without more interaction or time from my side, I'll close the PR and leave the code online in case someone later wants to refer to it.

For the record, we're using it internally because our setup already comes with the discussed optional dependencies. 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants