Skip to content

Commit c42c5db

Browse files
authored
Merge pull request #245 from wp-cli/fix/missing-coverage-files
Create multiple coverage files and merge them all together
2 parents 50d470b + d9fc30f commit c42c5db

File tree

2 files changed

+83
-16
lines changed

2 files changed

+83
-16
lines changed

src/Context/FeatureContext.php

Lines changed: 62 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,14 @@
99
use Behat\Testwork\Hook\Scope\BeforeSuiteScope;
1010
use Behat\Behat\Hook\Scope\AfterFeatureScope;
1111
use Behat\Behat\Hook\Scope\BeforeFeatureScope;
12+
use Behat\Behat\Hook\Scope\BeforeStepScope;
13+
use SebastianBergmann\CodeCoverage\Report\Clover;
14+
use SebastianBergmann\CodeCoverage\Driver\Selector;
15+
use SebastianBergmann\CodeCoverage\Filter;
16+
use SebastianBergmann\CodeCoverage\CodeCoverage;
17+
use SebastianBergmann\Environment\Runtime;
1218
use RuntimeException;
19+
use DirectoryIterator;
1320
use WP_CLI\Process;
1421
use WP_CLI\Utils;
1522
use WP_CLI\WpOrgApi;
@@ -131,6 +138,13 @@ class FeatureContext implements SnippetAcceptingContext {
131138
*/
132139
private $scenario;
133140

141+
/**
142+
* Line of the current step.
143+
*
144+
* @var int
145+
*/
146+
private $step_line = 0;
147+
134148
/**
135149
* @BeforeFeature
136150
*/
@@ -145,11 +159,19 @@ public function store_scenario( BeforeScenarioScope $scope ) {
145159
$this->scenario = $scope->getScenario();
146160
}
147161

162+
/**
163+
* @BeforeStep
164+
*/
165+
public function store_step( BeforeStepScope $scope ) {
166+
$this->step_line = $scope->getStep()->getLine();
167+
}
168+
148169
/**
149170
* @AfterScenario
150171
*/
151172
public function forget_scenario( AfterScenarioScope $scope ) {
152-
$this->scenario = null;
173+
$this->step_line = 0;
174+
$this->scenario = null;
153175
}
154176

155177
/**
@@ -159,6 +181,34 @@ public static function forget_feature( AfterFeatureScope $scope ) {
159181
self::$feature = null;
160182
}
161183

184+
/**
185+
* @AfterSuite
186+
*/
187+
public static function merge_coverage_reports() {
188+
$with_code_coverage = (string) getenv( 'WP_CLI_TEST_COVERAGE' );
189+
190+
if ( ! \in_array( $with_code_coverage, [ 'true', '1' ], true ) ) {
191+
return;
192+
}
193+
194+
$filter = new Filter();
195+
$coverage = new CodeCoverage(
196+
( new Selector() )->forLineCoverage( $filter ),
197+
$filter
198+
);
199+
200+
foreach ( new DirectoryIterator( self::$behat_run_dir . '/build/logs' ) as $file ) {
201+
if ( ! $file->isFile() || 'cov' !== $file->getExtension() ) {
202+
continue;
203+
}
204+
205+
$coverage->merge( include $file->getPathname() );
206+
unlink( $file->getPathname() );
207+
}
208+
209+
( new Clover() )->process( $coverage, self::$behat_run_dir . '/build/logs/behat-coverage.xml' );
210+
}
211+
162212
/**
163213
* Get the path to the Composer vendor folder.
164214
*
@@ -298,7 +348,14 @@ private static function get_process_env_variables() {
298348
];
299349

300350
$with_code_coverage = (string) getenv( 'WP_CLI_TEST_COVERAGE' );
351+
301352
if ( \in_array( $with_code_coverage, [ 'true', '1' ], true ) ) {
353+
$has_coverage_driver = ( new Runtime() )->hasXdebug() || ( new Runtime() )->hasPCOV();
354+
355+
if ( ! $has_coverage_driver ) {
356+
throw new RuntimeException( 'No coverage driver available. Re-run script with `--xdebug` flag, i.e. `composer behat -- --xdebug`.' );
357+
}
358+
302359
$coverage_require_file = self::$behat_run_dir . '/vendor/wp-cli/wp-cli-tests/utils/generate-coverage.php';
303360
if ( ! file_exists( $coverage_require_file ) ) {
304361
// This file is not vendored inside the wp-cli-tests project
@@ -871,8 +928,8 @@ public function download_phar( $version = 'same' ) {
871928
);
872929

873930
$this->variables['PHAR_PATH'] = $this->variables['RUN_DIR'] . '/'
874-
. uniqid( 'wp-cli-download-', true )
875-
. '.phar';
931+
. uniqid( 'wp-cli-download-', true )
932+
. '.phar';
876933

877934
Process::create(
878935
Utils\esc_cmd(
@@ -957,6 +1014,8 @@ public function proc( $command, $assoc_args = [], $path = '' ) {
9571014
$env['BEHAT_SCENARIO_TITLE'] = $this->scenario->getTitle();
9581015
}
9591016

1017+
$env['BEHAT_STEP_LINE'] = $this->step_line;
1018+
9601019
$env['WP_CLI_TEST_DBTYPE'] = self::$db_type;
9611020

9621021
if ( isset( $this->variables['RUN_DIR'] ) ) {

utils/generate-coverage.php

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,32 @@
11
<?php
22

33
/**
4-
* This script is added via `--require` to the WP-CLI commands executed by the Behat test runner.
4+
* This script is added via the `WP_CLI_REQUIRE` environment variable to the WP-CLI commands executed by the Behat test runner.
55
* It starts coverage collection right away and registers a shutdown hook to complete it
66
* after the respective WP-CLI command has finished.
77
*/
88

99
use SebastianBergmann\CodeCoverage\CodeCoverage;
1010
use SebastianBergmann\CodeCoverage\Driver\Selector;
1111
use SebastianBergmann\CodeCoverage\Filter;
12-
use SebastianBergmann\CodeCoverage\Report\Clover;
12+
use SebastianBergmann\CodeCoverage\Report\PHP as PHPReport;
1313

14+
/*
15+
* The names of the current feature and scenario are passed on from the Behat test runner
16+
* to this script through environment variables.
17+
*/
18+
$feature = getenv( 'BEHAT_FEATURE_TITLE' );
19+
$scenario = getenv( 'BEHAT_SCENARIO_TITLE' );
20+
$step_line = (int) getenv( 'BEHAT_STEP_LINE' );
21+
$name = "{$feature} - {$scenario} - {$step_line}";
22+
23+
/*
24+
* Do not run coverage if they are empty, which means we are running some command
25+
* during test preparation, e.g. the `wp core download` in `FeatureContext::prepare()`.
26+
*/
27+
if ( empty( $feature ) | empty( $scenario ) ) {
28+
return;
29+
}
1430

1531
$project_dir = (string) getenv( 'TEST_RUN_DIR' );
1632

@@ -65,30 +81,22 @@ function ( $file ) {
6581
$filter
6682
);
6783

68-
/*
69-
* The names of the current feature and scenario are passed on from the Behat test runner
70-
* to this script through environment variables `BEHAT_FEATURE_TITLE` & `BEHAT_SCENARIO_TITLE`.
71-
*/
72-
$feature = getenv( 'BEHAT_FEATURE_TITLE' );
73-
$scenario = getenv( 'BEHAT_SCENARIO_TITLE' );
74-
$name = "{$feature} - {$scenario}";
75-
7684
$coverage->start( $name );
7785

7886
register_shutdown_function(
79-
static function () use ( $coverage, $feature, $scenario, $name, $project_dir ) {
87+
static function () use ( $coverage, $feature, $scenario, $step_line, $name, $project_dir ) {
8088
$coverage->stop();
8189

8290
$feature_suffix = preg_replace( '/[^a-z0-9]+/', '-', strtolower( $feature ) );
8391
$scenario_suffix = preg_replace( '/[^a-z0-9]+/', '-', strtolower( $scenario ) );
8492
$db_type = strtolower( getenv( 'WP_CLI_TEST_DBTYPE' ) );
85-
$destination = "$project_dir/build/logs/$feature_suffix-$scenario_suffix-$db_type.xml";
93+
$destination = "$project_dir/build/logs/$feature_suffix-$scenario_suffix-$step_line-$db_type.cov";
8694

8795
$dir = dirname( $destination );
8896
if ( ! file_exists( $dir ) ) {
8997
mkdir( $dir, 0777, true /*recursive*/ );
9098
}
9199

92-
( new Clover() )->process( $coverage, $destination, $name );
100+
( new PHPReport() )->process( $coverage, $destination );
93101
}
94102
);

0 commit comments

Comments
 (0)