Issue #3254726 by longwave, mondrake: Remove SimpleTest support from run-tests.sh, TestDiscovery and TestRunnerKernel

merge-requests/1789/head
catch 2022-02-07 16:27:25 +00:00
parent d60ba4d876
commit fece49c31a
7 changed files with 60 additions and 458 deletions

View File

@ -2,7 +2,6 @@
namespace Drupal\Core\Test\RunTests;
use Drupal\simpletest\TestBase;
use PHPUnit\Framework\TestCase;
/**
@ -24,7 +23,7 @@ class TestFileParser {
public function getTestListFromFile($file) {
$test_list = $this->parseContents(file_get_contents($file));
return array_filter($test_list, function ($class) {
return (is_subclass_of($class, TestCase::class) || is_subclass_of($class, TestBase::class));
return is_subclass_of($class, TestCase::class);
});
}

View File

@ -8,10 +8,11 @@ use Drupal\Component\Utility\NestedArray;
use Drupal\Core\Extension\ExtensionDiscovery;
use Drupal\Core\Test\Exception\MissingGroupException;
use Drupal\TestTools\PhpUnitCompatibility\ClassWriter;
use PHPUnit\Util\Test;
/**
* Discovers available tests.
*
* @internal
*/
class TestDiscovery {
@ -98,8 +99,6 @@ class TestDiscovery {
if (!isset($existing["Drupal\\$name\\"])) {
$this->classLoader->addPsr4("Drupal\\$name\\", "$base_path/src");
}
// Add Simpletest test namespace.
$this->testNamespaces["Drupal\\$name\\Tests\\"][] = "$base_path/src/Tests";
// Add PHPUnit test namespaces.
$this->testNamespaces["Drupal\\Tests\\$name\\Unit\\"][] = "$base_path/tests/src/Unit";
@ -182,20 +181,6 @@ class TestDiscovery {
// abstract class, trait or test fixture.
continue;
}
// Skip this test class if it is a Simpletest-based test and requires
// unavailable modules. TestDiscovery should not filter out module
// requirements for PHPUnit-based test classes.
// @todo Move this behavior to \Drupal\simpletest\TestBase so tests can be
// marked as skipped, instead.
// @see https://www.drupal.org/node/1273478
if ($info['type'] == 'Simpletest') {
if (!empty($info['requires']['module'])) {
if (array_diff($info['requires']['module'], $this->availableExtensions['module'])) {
continue;
}
}
}
foreach ($info['groups'] as $group) {
$list[$group][$classname] = $info;
}
@ -322,11 +307,8 @@ class TestDiscovery {
* - group: The test's first @group (parsed from PHPDoc annotations).
* - groups: All of the test's @group annotations, as an array (parsed from
* PHPDoc annotations).
* - requires: An associative array containing test requirements parsed from
* PHPDoc annotations:
* - module: List of Drupal module extension names the test depends on.
*
* @throws \Drupal\simpletest\Exception\MissingGroupException
* @throws \Drupal\Core\Test\Exception\MissingGroupException
* If the class does not have a @group annotation.
*/
public static function getTestInfo($classname, $doc_comment = NULL) {
@ -363,14 +345,7 @@ class TestDiscovery {
}
$info['group'] = $annotations['group'];
$info['groups'] = $annotations['groups'];
// Sort out PHPUnit-runnable tests by type.
if ($testsuite = static::getPhpunitTestSuite($classname)) {
$info['type'] = 'PHPUnit-' . $testsuite;
}
else {
$info['type'] = 'Simpletest';
}
$info['type'] = 'PHPUnit-' . static::getPhpunitTestSuite($classname);
if (!empty($annotations['coversDefaultClass'])) {
$info['description'] = 'Tests ' . $annotations['coversDefaultClass'] . '.';
@ -378,9 +353,6 @@ class TestDiscovery {
else {
$info['description'] = static::parseTestClassSummary($doc_comment);
}
if (isset($annotations['dependencies'])) {
$info['requires']['module'] = array_map('trim', explode(',', $annotations['dependencies']));
}
return $info;
}
@ -414,42 +386,6 @@ class TestDiscovery {
return implode(' ', $summary);
}
/**
* Parses annotations in the phpDoc of a test class.
*
* @param \ReflectionClass $class
* The reflected test class.
*
* @return array
* An associative array that contains all annotations on the test class;
* typically including:
* - group: A list of @group values.
* - requires: An associative array of @requires values; e.g.:
* - module: A list of Drupal module dependencies that are required to
* exist.
*
* @see \PHPUnit\Util\Test::parseTestMethodAnnotations()
* @see http://phpunit.de/manual/current/en/incomplete-and-skipped-tests.html#incomplete-and-skipped-tests.skipping-tests-using-requires
*/
public static function parseTestClassAnnotations(\ReflectionClass $class) {
$annotations = Test::parseTestMethodAnnotations($class->getName())['class'];
// @todo Enhance PHPUnit upstream to allow for custom @requires identifiers.
// @see \PHPUnit\Util\Test::getRequirements()
// @todo Add support for 'PHP', 'OS', 'function', 'extension'.
// @see https://www.drupal.org/node/1273478
if (isset($annotations['requires'])) {
foreach ($annotations['requires'] as $i => $value) {
[$type, $value] = explode(' ', $value, 2);
if ($type === 'module') {
$annotations['requires']['module'][$value] = $value;
unset($annotations['requires'][$i]);
}
}
}
return $annotations;
}
/**
* Determines the phpunit testsuite for a given classname, based on namespace.
*

View File

@ -4,12 +4,13 @@ namespace Drupal\Core\Test;
use Drupal\Core\DrupalKernel;
use Drupal\Core\Extension\Extension;
use Drupal\Core\Extension\ExtensionDiscovery;
use Drupal\Core\Site\Settings;
use Symfony\Component\HttpFoundation\Request;
/**
* Kernel for run-tests.sh.
*
* @internal
*/
class TestRunnerKernel extends DrupalKernel {
@ -40,13 +41,6 @@ class TestRunnerKernel extends DrupalKernel {
$this->moduleData = [
'system' => new Extension($this->root, 'module', 'core/modules/system/system.info.yml', 'system.module'),
];
// In order to support Simpletest in Drupal 9 conditionally include the
// module.
$extensions = (new ExtensionDiscovery($this->root, FALSE, [], 'ignore_site_path_does_not_exist'))->scan('module', FALSE);
if (isset($extensions['simpletest'])) {
$this->moduleList['simpletest'] = 0;
$this->moduleData['simpletest'] = $extensions['simpletest'];
}
}
/**

View File

@ -42,7 +42,6 @@ trait TestSetupTrait {
/**
* The public file directory for the test environment.
*
* @see \Drupal\simpletest\TestBase::prepareEnvironment()
* @see \Drupal\Tests\BrowserTestBase::prepareEnvironment()
*
* @var string
@ -59,7 +58,6 @@ trait TestSetupTrait {
/**
* The private file directory for the test environment.
*
* @see \Drupal\simpletest\TestBase::prepareEnvironment()
* @see \Drupal\Tests\BrowserTestBase::prepareEnvironment()
*
* @var string
@ -88,7 +86,6 @@ trait TestSetupTrait {
* This value has to match the temporary directory created in
* install_base_system() for test installs.
*
* @see \Drupal\simpletest\TestBase::prepareEnvironment()
* @see \Drupal\Tests\BrowserTestBase::prepareEnvironment()
* @see install_base_system()
*
@ -104,7 +101,7 @@ trait TestSetupTrait {
protected $testId;
/**
* Returns the database connection to the site running Simpletest.
* Returns the database connection to the site under test.
*
* @return \Drupal\Core\Database\Connection
* The database connection to use for inserting assertions.

View File

@ -11,7 +11,6 @@ use Drupal\Component\Utility\Html;
use Drupal\Component\Utility\Timer;
use Drupal\Core\Composer\Composer;
use Drupal\Core\Database\Database;
use Drupal\Core\File\Exception\FileException;
use Drupal\Core\Test\EnvironmentCleaner;
use Drupal\Core\Test\PhpUnitTestRunner;
use Drupal\Core\Test\RunTests\TestFileParser;
@ -22,7 +21,6 @@ use Drupal\TestTools\PhpUnitCompatibility\ClassWriter;
use PHPUnit\Framework\TestCase;
use PHPUnit\Runner\Version;
use Symfony\Component\Console\Output\ConsoleOutput;
use Symfony\Component\Filesystem\Filesystem as SymfonyFilesystem;
use Symfony\Component\HttpFoundation\Request;
// Define some colors for display.
@ -242,7 +240,7 @@ All arguments are long options.
--sqlite A pathname to use for the SQLite database of the test runner.
Required unless this script is executed with a working Drupal
installation that has Simpletest module installed.
installation.
A relative pathname is interpreted relative to the Drupal root
directory.
Note that ':memory:' cannot be used, because this script spawns
@ -288,7 +286,7 @@ All arguments are long options.
Runs just tests from the specified test type, for example
run-tests.sh
(i.e. --types "Simpletest,PHPUnit-Functional")
(i.e. --types "PHPUnit-Unit,PHPUnit-Kernel")
--directory Run all tests found within the specified file directory.
@ -345,9 +343,8 @@ sudo -u [wwwrun|www-data|etc] php ./core/scripts/{$args['script']}
sudo -u [wwwrun|www-data|etc] php ./core/scripts/{$args['script']}
--url http://example.com/ --class "Drupal\block\Tests\BlockTest"
Without a preinstalled Drupal site and enabled Simpletest module, specify a
SQLite database pathname to create and the default database connection info to
use in tests:
Without a preinstalled Drupal site, specify a SQLite database pathname to create
and the default database connection info to use in tests:
sudo -u [wwwrun|www-data|etc] php ./core/scripts/{$args['script']}
--sqlite /tmpfs/drupal/test.sqlite
@ -626,9 +623,8 @@ function simpletest_script_setup_database($new = FALSE) {
}
Database::addConnectionInfo('default', 'default', $databases['default']['default']);
// If no --sqlite parameter has been passed, then Simpletest module is assumed
// to be installed, so the test runner database connection is the default
// database connection.
// If no --sqlite parameter has been passed, then the test runner database
// connection is the default database connection.
if (empty($args['sqlite'])) {
$sqlite = FALSE;
$databases['test-runner']['default'] = $databases['default']['default'];
@ -684,10 +680,10 @@ function simpletest_script_setup_database($new = FALSE) {
}
}
}
// Verify that the Simpletest database schema exists by checking one table.
// Verify that the test result database schema exists by checking one table.
try {
if (!$schema->tableExists('simpletest')) {
simpletest_script_print_error('Missing Simpletest database schema. Either install Simpletest module or use the --sqlite parameter.');
simpletest_script_print_error('Missing test result database schema. Use the --sqlite parameter.');
exit(SIMPLETEST_SCRIPT_EXIT_FAILURE);
}
}
@ -780,10 +776,6 @@ function simpletest_script_execute_batch($test_classes) {
$args['repeat'] = -1;
}
}
// Free-up space by removing any potentially created resources.
if (!$args['keep-results']) {
simpletest_script_cleanup($child['test_id'], $child['class'], $status['exitcode']);
}
// Remove this child.
unset($children[$cid]);
@ -820,47 +812,10 @@ function simpletest_script_run_one_test($test_id, $test_class) {
global $args;
try {
// Default to status = success. This could mean that we didn't discover any
// tests and that none ran.
$status = SIMPLETEST_SCRIPT_EXIT_SUCCESS;
if (strpos($test_class, '::') > 0) {
[$class_name, $method] = explode('::', $test_class, 2);
$methods = [$method];
}
else {
$class_name = $test_class;
// Use empty array to run all the test methods.
$methods = [];
}
$test = new $class_name($test_id);
if ($args['suppress-deprecations']) {
putenv('SYMFONY_DEPRECATIONS_HELPER=disabled');
}
if (is_subclass_of($test_class, TestCase::class)) {
$status = simpletest_script_run_phpunit($test_id, $test_class);
}
// If we aren't running a PHPUnit-based test, then we might have a
// Simpletest-based one. Ensure that: 1) The simpletest framework exists,
// and 2) that our test belongs to that framework.
elseif (class_exists('Drupal\simpletest\TestBase') && is_subclass_of($test_class, 'Drupal\simpletest\TestBase')) {
$test->dieOnFail = (bool) $args['die-on-fail'];
$test->verbose = (bool) $args['verbose'];
$test->run($methods);
simpletest_script_reporter_display_summary($test_class, $test->results);
$status = SIMPLETEST_SCRIPT_EXIT_SUCCESS;
// Finished, kill this runner.
if ($test->results['#fail'] || $test->results['#exception']) {
$status = SIMPLETEST_SCRIPT_EXIT_FAILURE;
}
}
// If the test is not a PHPUnit test, and either we don't have the
// Simpletest module or the \Drupal\simpletest\TestBase class available.
else {
simpletest_script_print_error(sprintf('Can not run %s. If this is a WebTestBase test the simpletest module must be installed. See https://www.drupal.org/node/3030340', $test_class));
$status = SIMPLETEST_SCRIPT_EXIT_FAILURE;
}
$status = simpletest_script_run_phpunit($test_id, $test_class);
exit($status);
}
// DrupalTestCase::run() catches exceptions already, so this is only reached
@ -905,112 +860,6 @@ function simpletest_script_command($test_id, $test_class) {
return $command;
}
/**
* Removes all remnants of a test runner.
*
* In case a fatal error occurs after the test site has been fully setup and
* the error happens in many tests, the environment that executes the tests can
* easily run out of memory or disk space. This function ensures that all
* created resources are properly cleaned up after every executed test.
*
* This clean-up only exists in this script, since SimpleTest module itself does
* not use isolated sub-processes for each test being run, so a fatal error
* halts not only the test, but also the test runner (i.e., the parent site).
*
* @param int $test_id
* The test ID of the test run.
* @param string $test_class
* The class name of the test run.
* @param int $exitcode
* The exit code of the test runner.
*
* @see simpletest_script_run_one_test()
*/
function simpletest_script_cleanup($test_id, $test_class, $exitcode) {
if (is_subclass_of($test_class, TestCase::class)) {
// PHPUnit test, move on.
return;
}
// Retrieve the last database prefix used for testing.
try {
$last_test = TestDatabase::lastTestGet($test_id);
$db_prefix = $last_test['last_prefix'];
}
catch (Exception $e) {
echo (string) $e;
exit(SIMPLETEST_SCRIPT_EXIT_EXCEPTION);
}
// If no database prefix was found, then the test was not set up correctly.
if (empty($db_prefix)) {
echo "\nFATAL $test_class: Found no database prefix for test ID $test_id. (Check whether setUp() is invoked correctly.)";
return;
}
// Do not output verbose cleanup messages in case of a positive exitcode.
$output = !empty($exitcode);
$messages = [];
$messages[] = "- Found database prefix '$db_prefix' for test ID $test_id.";
// Read the log file in case any fatal errors caused the test to crash.
try {
(new TestDatabase($db_prefix))->logRead($test_id, $last_test['test_class']);
}
catch (Exception $e) {
echo (string) $e;
exit(SIMPLETEST_SCRIPT_EXIT_EXCEPTION);
}
// Check whether a test site directory was setup already.
// @see \Drupal\simpletest\TestBase::prepareEnvironment()
$test_db = new TestDatabase($db_prefix);
$test_directory = DRUPAL_ROOT . '/' . $test_db->getTestSitePath();
if (is_dir($test_directory)) {
// Output the error_log.
if (is_file($test_directory . '/error.log')) {
if ($errors = file_get_contents($test_directory . '/error.log')) {
$output = TRUE;
$messages[] = $errors;
}
}
// Delete the test site directory.
// simpletest_clean_temporary_directories() cannot be used here, since it
// would also delete file directories of other tests that are potentially
// running concurrently.
try {
\Drupal::service('file_system')->deleteRecursive($test_directory, ['\Drupal\Tests\BrowserTestBase', 'filePreDeleteCallback']);
$messages[] = "- Removed test site directory.";
}
catch (FileException $e) {
// Ignore failed deletes.
}
}
// Clear out all database tables from the test.
try {
$schema = Database::getConnection('default', 'default')->schema();
$count = 0;
foreach ($schema->findTables($db_prefix . '%') as $table) {
$schema->dropTable($table);
$count++;
}
}
catch (Exception $e) {
echo (string) $e;
exit(SIMPLETEST_SCRIPT_EXIT_EXCEPTION);
}
if ($count) {
$messages[] = "- Removed $count leftover tables.";
}
if ($output) {
echo implode("\n", $messages);
echo "\n";
}
}
/**
* Get list of tests based on arguments.
*

View File

@ -84,46 +84,23 @@ class TestDiscoveryTest extends UnitTestCase {
'\Drupal\Tests\file\Kernel\FileItemValidationTest',
];
// Simpletest classes can not be autoloaded in a PHPUnit test, therefore
// provide a docblock.
$tests[] = [
// Expected result.
[
'name' => 'Drupal\simpletest\Tests\ExampleSimpleTest',
'group' => 'simpletest',
'groups' => ['simpletest'],
'description' => 'Tests the Simpletest UI internal browser.',
'type' => 'Simpletest',
],
// Classname.
'Drupal\simpletest\Tests\ExampleSimpleTest',
// Doc block.
"/**
* Tests the Simpletest UI internal browser.
*
* @group simpletest
*/
",
];
// Test with a different amount of leading spaces.
$tests[] = [
// Expected result.
[
'name' => 'Drupal\simpletest\Tests\ExampleSimpleTest',
'group' => 'simpletest',
'groups' => ['simpletest'],
'description' => 'Tests the Simpletest UI internal browser.',
'type' => 'Simpletest',
'name' => 'Drupal\Tests\ExampleSimpleTest',
'group' => 'test',
'groups' => ['test'],
'description' => 'Example test.',
'type' => 'PHPUnit-Unit',
],
// Classname.
'Drupal\simpletest\Tests\ExampleSimpleTest',
'Drupal\Tests\ExampleSimpleTest',
// Doc block.
"/**
* Tests the Simpletest UI internal browser.
* Example test.
*
* @group simpletest
*/
* @group test
*/
",
];
@ -133,19 +110,19 @@ class TestDiscoveryTest extends UnitTestCase {
$tests[] = [
// Expected result.
[
'name' => 'Drupal\simpletest\Tests\ExampleSimpleTest',
'group' => 'simpletest',
'groups' => ['simpletest'],
'description' => 'Tests the Simpletest UI internal browser. * @',
'type' => 'Simpletest',
'name' => 'Drupal\Tests\ExampleSimpleTest',
'group' => 'test',
'groups' => ['test'],
'description' => 'Example test. * @',
'type' => 'PHPUnit-Unit',
],
// Classname.
'Drupal\simpletest\Tests\ExampleSimpleTest',
'Drupal\Tests\ExampleSimpleTest',
// Doc block.
"/**
* Tests the Simpletest UI internal browser. * @
* Example test. * @
*
* @group simpletest
* @group test
*/
",
];
@ -154,20 +131,20 @@ class TestDiscoveryTest extends UnitTestCase {
$tests[] = [
// Expected result.
[
'name' => 'Drupal\simpletest\Tests\ExampleSimpleTest',
'group' => 'Test',
'groups' => ['Test', 'simpletest'],
'description' => 'Tests the Simpletest UI internal browser.',
'type' => 'Simpletest',
'name' => 'Drupal\Tests\ExampleSimpleTest',
'group' => 'test1',
'groups' => ['test1', 'test2'],
'description' => 'Example test.',
'type' => 'PHPUnit-Unit',
],
// Classname.
'Drupal\simpletest\Tests\ExampleSimpleTest',
'Drupal\Tests\ExampleSimpleTest',
// Doc block.
"/**
* Tests the Simpletest UI internal browser.
* Example test.
*
* @group Test
* @group simpletest
* @group test1
* @group test2
*/
",
];
@ -176,20 +153,20 @@ class TestDiscoveryTest extends UnitTestCase {
$tests['many-group-annotations'] = [
// Expected result.
[
'name' => 'Drupal\simpletest\Tests\ExampleSimpleTest',
'group' => 'Test',
'groups' => ['Test', 'simpletest', 'another', 'more', 'many', 'enough', 'whoa'],
'description' => 'Tests the Simpletest UI internal browser.',
'type' => 'Simpletest',
'name' => 'Drupal\Tests\ExampleSimpleTest',
'group' => 'test1',
'groups' => ['test1', 'test2', 'another', 'more', 'many', 'enough', 'whoa'],
'description' => 'Example test.',
'type' => 'PHPUnit-Unit',
],
// Classname.
'Drupal\simpletest\Tests\ExampleSimpleTest',
'Drupal\Tests\ExampleSimpleTest',
// Doc block.
"/**
* Tests the Simpletest UI internal browser.
* Example test.
*
* @group Test
* @group simpletest
* @group test1
* @group test2
* @group another
* @group more
* @group many
@ -199,70 +176,24 @@ class TestDiscoveryTest extends UnitTestCase {
",
];
// @dependencies annotation.
$tests[] = [
// Expected result.
[
'name' => 'Drupal\simpletest\Tests\ExampleSimpleTest',
'description' => 'Tests the Simpletest UI internal browser.',
'type' => 'Simpletest',
'requires' => ['module' => ['test']],
'group' => 'simpletest',
'groups' => ['simpletest'],
],
// Classname.
'Drupal\simpletest\Tests\ExampleSimpleTest',
// Doc block.
"/**
* Tests the Simpletest UI internal browser.
*
* @dependencies test
* @group simpletest
*/
",
];
// Multiple @dependencies annotation.
$tests[] = [
// Expected result.
[
'name' => 'Drupal\simpletest\Tests\ExampleSimpleTest',
'description' => 'Tests the Simpletest UI internal browser.',
'type' => 'Simpletest',
'requires' => ['module' => ['test', 'test1', 'test2']],
'group' => 'simpletest',
'groups' => ['simpletest'],
],
// Classname.
'Drupal\simpletest\Tests\ExampleSimpleTest',
// Doc block.
"/**
* Tests the Simpletest UI internal browser.
*
* @dependencies test, test1, test2
* @group simpletest
*/
",
];
// Multi-line summary line.
$tests[] = [
// Expected result.
[
'name' => 'Drupal\simpletest\Tests\ExampleSimpleTest',
'description' => 'Tests the Simpletest UI internal browser. And the summary line continues an there is no gap to the annotation.',
'type' => 'Simpletest',
'group' => 'simpletest',
'groups' => ['simpletest'],
'name' => 'Drupal\Tests\ExampleSimpleTest',
'description' => 'Example test. And the summary line continues and there is no gap to the annotation.',
'type' => 'PHPUnit-Unit',
'group' => 'test',
'groups' => ['test'],
],
// Classname.
'Drupal\simpletest\Tests\ExampleSimpleTest',
'Drupal\Tests\ExampleSimpleTest',
// Doc block.
"/**
* Tests the Simpletest UI internal browser. And the summary line continues an
* there is no gap to the annotation.
* Example test. And the summary line continues and there is no gap to the
* annotation.
*
* @group simpletest
* @group test
*/
",
];

View File

@ -1,104 +0,0 @@
<?php
namespace Drupal\Tests\Core\Test;
use Composer\Autoload\ClassLoader;
use Drupal\Core\Extension\Extension;
use Drupal\Core\Test\TestRunnerKernel;
use org\bovigo\vfs\vfsStream;
use PHPUnit\Framework\TestCase;
/**
* @coversDefaultClass \Drupal\Core\Test\TestRunnerKernel
* @runTestsInSeparateProcesses
* @preserveGlobalState disabled
* @group Test
* @group simpletest
*/
class TestRunnerKernelTest extends TestCase {
/**
* Data provider for self::testConstructor().
*/
public function providerTestConstructor() {
$core = [
'core' => [
'modules' => [
'system' => [
'system.info.yml' => 'type: module',
],
],
],
];
$tests = [];
$tests['simpletest-in-contrib'] = [
$core + [
'modules' => [
'contrib' => [
'simpletest' => [
'simpletest.info.yml' => 'type: module',
],
],
],
],
'modules/contrib/simpletest',
];
$tests['simpletest-simpletest-in-contrib'] = [
$core + [
'modules' => [
'contrib' => [
'simpletest-simpletest' => [
'simpletest.info.yml' => 'type: module',
],
],
],
],
'modules/contrib/simpletest-simpletest',
];
$tests['simpletest-no-contrib'] = [
$core + [
'modules' => [
'simpletest' => [
'simpletest.info.yml' => 'type: module',
],
],
],
'modules/simpletest',
];
$tests['no-simpletest'] = [
$core,
FALSE,
];
return $tests;
}
/**
* @covers ::__construct
* @dataProvider providerTestConstructor
*/
public function testConstructor($file_system, $expected) {
// Set up the file system.
$vfs = vfsStream::setup('root');
vfsStream::create($file_system, $vfs);
$kernel = new TestRunnerKernel('prod', new ClassLoader(), FALSE, vfsStream::url('root'));
$class = new \ReflectionClass(TestRunnerKernel::class);
$instance_method = $class->getMethod('moduleData');
$instance_method->setAccessible(TRUE);
/** @var \Drupal\Core\Extension\Extension $extension */
$extension = $instance_method->invoke($kernel, 'simpletest');
if ($expected === FALSE) {
$this->assertFalse($extension);
}
else {
$this->assertInstanceOf(Extension::class, $extension);
$this->assertSame($expected, $extension->getPath());
}
}
}