Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions tests/phpunit/includes/abstract-testcase.php
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,8 @@ public function set_up() {

set_time_limit( 0 );

$this->skip_default_excluded_groups();

$this->factory = static::factory();

if ( ! self::$ignore_files ) {
Expand Down Expand Up @@ -143,6 +145,43 @@ public function set_up() {
add_filter( 'wp_hash_password_options', array( $this, 'wp_hash_password_options' ), 1, 2 );
}

/**
* Skips tests that belong to groups excluded by default unless those groups were explicitly requested.
*/
protected function skip_default_excluded_groups() {
$skipped_groups = self::get_default_excluded_groups_for_test( $this->getGroups() );

if ( $skipped_groups ) {
$this->markTestSkipped(
sprintf(
'This test belongs to a group that is skipped by default: %s. Use --group %s to run it.',
implode( ', ', $skipped_groups ),
$skipped_groups[0]
)
);
}
}

/**
* Returns the default-excluded groups that apply to a test and were not explicitly requested.
*
* @param string[] $groups Test groups.
* @return string[] Matching excluded groups.
*/
public static function get_default_excluded_groups_for_test( array $groups ) {
$default_excluded_groups = WP_PHPUnit_Util_Getopt::get_skipped_groups();

return array_values(
array_filter(
$groups,
static function ( $group ) use ( $default_excluded_groups ) {
return in_array( $group, $default_excluded_groups, true )
&& ! WP_PHPUnit_Util_Getopt::is_group_requested( $group );
}
)
);
}

/**
* Sets the bcrypt cost option for password hashing during tests.
*
Expand Down
82 changes: 71 additions & 11 deletions tests/phpunit/includes/bootstrap.php
Original file line number Diff line number Diff line change
Expand Up @@ -345,42 +345,83 @@ function wp_tests_options( $value ) {
* how you call phpunit has no effect.
*/
class WP_PHPUnit_Util_Getopt {

public function __construct( $argv ) {
/**
* Groups that are skipped by default for the current test run.
*
* @var array<string, bool>
*/
protected static $skipped_groups = array();

/**
* Groups that were explicitly requested via the command line.
*
* @var array<string, bool>
*/
protected static $requested_groups = array();

/**
* Initializes the default skipped groups for the current test mode.
*
* @return array<string, bool> The groups skipped by default.
*/
protected static function get_default_skipped_groups() {
$skipped_groups = array(
'ajax' => true,
'ms-files' => true,
'external-http' => true,
'ajax' => true,
'ms-files' => true,
'external-http' => true,
'html-api-html5lib-tests' => true,
);

if ( defined( 'WP_TESTS_MULTISITE' ) && WP_TESTS_MULTISITE ) {
$skipped_groups['ms-excluded'] = true;
$skipped_groups['oembed-headers'] = true;
} else {
$skipped_groups['ms-required'] = true;
}

return $skipped_groups;
}

/**
* Resets the parsed command line state.
*/
public static function reset() {
self::$skipped_groups = self::get_default_skipped_groups();
self::$requested_groups = array();
}

public function __construct( $argv ) {
self::reset();

while ( current( $argv ) ) {
$option = current( $argv );
$value = next( $argv );

switch ( $option ) {
case '--exclude-group':
foreach ( $skipped_groups as $group_name => $skipped ) {
$skipped_groups[ $group_name ] = false;
}
// PHPUnit replaces XML exclusions when this option is provided.
// Keep our default skipped groups active unless they are requested explicitly.
continue 2;
case '--group':
$groups = explode( ',', $value );
foreach ( $groups as $group ) {
self::$requested_groups[ $group ] = true;

if ( is_numeric( $group ) || preg_match( '/^(UT|Plugin)\d+$/', $group ) ) {
WP_UnitTestCase::forceTicket( $group );
}
}

foreach ( $skipped_groups as $group_name => $skipped ) {
foreach ( self::$skipped_groups as $group_name => $skipped ) {
if ( in_array( $group_name, $groups, true ) ) {
$skipped_groups[ $group_name ] = false;
self::$skipped_groups[ $group_name ] = false;
}
}
continue 2;
}
}

$skipped_groups = array_filter( $skipped_groups );
$skipped_groups = array_filter( self::$skipped_groups );
foreach ( $skipped_groups as $group_name => $skipped ) {
echo sprintf( 'Not running %1$s tests. To execute these, use --group %1$s.', $group_name ) . PHP_EOL;
}
Expand All @@ -392,5 +433,24 @@ public function __construct( $argv ) {
echo PHP_EOL;
}
}

/**
* Returns the groups that are still skipped by default for this run.
*
* @return string[]
*/
public static function get_skipped_groups() {
return array_keys( array_filter( self::$skipped_groups ) );
}

/**
* Determines whether a group was explicitly requested via the command line.
*
* @param string $group Group name.
* @return bool Whether the group was explicitly requested.
*/
public static function is_group_requested( $group ) {
return isset( self::$requested_groups[ $group ] );
}
}
new WP_PHPUnit_Util_Getopt( $_SERVER['argv'] );
54 changes: 54 additions & 0 deletions tests/phpunit/tests/phpunit/groupFilters.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<?php
/**
* @group phpunit
*/
class Tests_PHPUnit_GroupFilters extends WP_UnitTestCase {

public function tear_down() {
WP_PHPUnit_Util_Getopt::reset();
parent::tear_down();
}

public function test_single_site_default_excluded_groups_are_reported() {
$this->assertSame(
array( 'ajax', 'external-http' ),
WP_UnitTestCase_Base::get_default_excluded_groups_for_test( array( 'ajax', 'external-http', 'query' ) )
);
}

public function test_requested_group_is_not_reported_as_default_excluded() {
ob_start();
new WP_PHPUnit_Util_Getopt(
array(
'phpunit',
'--group',
'ajax',
)
);
ob_end_clean();

$this->assertSame(
array(),
WP_UnitTestCase_Base::get_default_excluded_groups_for_test( array( 'ajax' ) )
);
}

public function test_exclude_group_does_not_clear_default_excluded_groups() {
ob_start();
new WP_PHPUnit_Util_Getopt(
array(
'phpunit',
'--exclude-group',
'import',
)
);
ob_end_clean();

$multisite_excluded_group = is_multisite() ? 'ms-excluded' : 'ms-required';

$this->assertSame(
array( 'ajax', $multisite_excluded_group ),
WP_UnitTestCase_Base::get_default_excluded_groups_for_test( array( 'ajax', $multisite_excluded_group ) )
);
}
}
Loading