From fd72f6c48e1c88930f0c59ccc94794eeaec92929 Mon Sep 17 00:00:00 2001 From: Kosta Harlan Date: Sun, 21 Jul 2019 20:34:23 +0200 Subject: [PATCH] Provide command to adjust phpunit.xml for code coverage Our current recommendation for adjusting PHPUnit configuration for extension code coverage reports is to manually modify tests/phpunit/suite.xml. This is cumbersome and annoying, since suite.xml is version controlled. This patch proposes a composer script to simplify editing the (non-version controlled) phpunit.xml config in the root of the MediaWiki repo. It is useful if you are interested in generating code coverage reports based on unit tests only, not integration tests. Usage: composer phpunit:coverage-edit -- extensions/GrowthExperiments When you're done, you can run `rm phpunit.xml` to switch back to the default phpunit.xml.dist. The script will use the default includes/src/maintenance directories, but a future improvement would be to identify the relevant directories via the AutoloadClasses property of extension.json. Another improvement would be to provide an option for passing arbitrary paths in core, in case you are working on tests for a specific class and want to generate coverage reports instantly. We could probably also remove dockerfiles/quibble-coverage/phpunit-suite-edit.py (which inspired this patch) and use composer phpunit:coverage-edit instead. Bug: T100294 Change-Id: Ia0ef41f67ca4a64b0d1ca0ddcee488c29630af0b --- autoload.php | 1 + composer.json | 6 +- .../ComposerPhpunitXmlCoverageEdit.php | 60 +++++++++++++++++++ 3 files changed, 65 insertions(+), 2 deletions(-) create mode 100644 includes/composer/ComposerPhpunitXmlCoverageEdit.php diff --git a/autoload.php b/autoload.php index eb54f7c592..413d315fae 100644 --- a/autoload.php +++ b/autoload.php @@ -298,6 +298,7 @@ $wgAutoloadLocalClasses = [ 'ComposerJson' => __DIR__ . '/includes/libs/composer/ComposerJson.php', 'ComposerLock' => __DIR__ . '/includes/libs/composer/ComposerLock.php', 'ComposerPackageModifier' => __DIR__ . '/includes/composer/ComposerPackageModifier.php', + 'ComposerPhpunitXmlCoverageEdit' => __DIR__ . '/includes/composer/ComposerPhpunitXmlCoverageEdit.php', 'ComposerVendorHtaccessCreator' => __DIR__ . '/includes/composer/ComposerVendorHtaccessCreator.php', 'ComposerVersionNormalizer' => __DIR__ . '/includes/composer/ComposerVersionNormalizer.php', 'CompressOld' => __DIR__ . '/maintenance/storage/compressOld.php', diff --git a/composer.json b/composer.json index ac89d71569..c1f9037fb3 100644 --- a/composer.json +++ b/composer.json @@ -97,7 +97,8 @@ "autoload": { "psr-0": { "ComposerHookHandler": "includes/composer", - "ComposerVendorHtaccessCreator": "includes/composer" + "ComposerVendorHtaccessCreator": "includes/composer", + "ComposerPhpunitXmlCoverageEdit":"includes/composer" } }, "autoload-dev": { @@ -121,7 +122,8 @@ "phpunit": "phpunit", "phpunit:unit": "phpunit --colors=always --testsuite=core:unit,extensions:unit,skins:unit", "phpunit:integration": "phpunit --colors=always --testsuite=core:integration,extensions:integration,skins:integration", - "phpunit:coverage": "phpunit --testsuite=core:unit --exclude-group Dump,Broken" + "phpunit:coverage": "phpunit --testsuite=core:unit --exclude-group Dump,Broken", + "phpunit:coverage-edit": "ComposerPhpunitXmlCoverageEdit::onEvent" }, "config": { "optimize-autoloader": true, diff --git a/includes/composer/ComposerPhpunitXmlCoverageEdit.php b/includes/composer/ComposerPhpunitXmlCoverageEdit.php new file mode 100644 index 0000000000..7db4b11bb3 --- /dev/null +++ b/includes/composer/ComposerPhpunitXmlCoverageEdit.php @@ -0,0 +1,60 @@ +getArguments(); + if ( count( $args ) !== 1 ) { + throw new InvalidArgumentException( 'Pass extensions/$extensionName as an argument, ' . + 'e.g. "composer phpunit:coverage-edit -- extensions/BoilerPlate"' ); + } + $project = current( $args ); + $phpunitXml = \PHPUnit\Util\Xml::loadFile( $IP . '/phpunit.xml.dist' ); + $whitelist = iterator_to_array( $phpunitXml->getElementsByTagName( 'whitelist' ) ); + /** @var DOMNode $childNode */ + foreach ( $whitelist as $childNode ) { + $childNode->parentNode->removeChild( $childNode ); + } + $whitelistElement = $phpunitXml->createElement( 'whitelist' ); + $whitelistElement->setAttribute( 'addUncoveredFilesFromWhitelist', 'false' ); + // TODO: Use AutoloadClasses from extension.json to load the relevant directories + foreach ( [ 'includes', 'src', 'maintenance' ] as $dir ) { + $dirElement = $phpunitXml->createElement( 'directory', $project . '/' . $dir ); + $dirElement->setAttribute( 'suffix', '.php' ); + $whitelistElement->appendChild( $dirElement ); + + } + $phpunitXml->getElementsByTagName( 'filter' )->item( 0 ) + ->appendChild( $whitelistElement ); + $phpunitXml->formatOutput = true; + $phpunitXml->save( $IP . '/phpunit.xml' ); + } +} -- 2.20.1