diff --git a/core/modules/views/tests/src/Kernel/ViewsKernelTestBase.php b/core/modules/views/tests/src/Kernel/ViewsKernelTestBase.php
index f53309b..f149b7f 100644
--- a/core/modules/views/tests/src/Kernel/ViewsKernelTestBase.php
+++ b/core/modules/views/tests/src/Kernel/ViewsKernelTestBase.php
@@ -11,7 +11,7 @@
/**
* Defines a base class for Views kernel testing.
*/
-class ViewsKernelTestBase extends KernelTestBase {
+abstract class ViewsKernelTestBase extends KernelTestBase {
use ViewResultAssertionTrait;
diff --git a/core/phpunit.xml.dist b/core/phpunit.xml.dist
index 2b45c64..951bd55 100644
--- a/core/phpunit.xml.dist
+++ b/core/phpunit.xml.dist
@@ -28,48 +28,16 @@
- ./tests/Drupal/Tests
- ./modules/*/tests/src/Unit
- ../modules/*/tests/src/Unit
- ../profiles/*/tests/src/Unit
- ../sites/*/modules/*/tests/src/Unit
-
- ./vendor
-
- ./drush/tests
+ ./tests/TestSuites/UnitTestSuite.php
- ./tests/Drupal/KernelTests
- ./modules/*/tests/src/Kernel
- ../modules/*/tests/src/Kernel
- ../profiles/*/tests/src/Kernel
- ../sites/*/modules/*/tests/src/Kernel
-
- ./vendor
-
- ./drush/tests
+ ./tests/TestSuites/KernelTestSuite.php
- ./tests/Drupal/FunctionalTests
- ./modules/*/tests/src/Functional
- ../modules/*/tests/src/Functional
- ../profiles/*/tests/src/Functional
- ../sites/*/modules/*/tests/src/Functional
-
- ./vendor
-
- ./drush/tests
+ ./tests/TestSuites/FunctionalTestSuite.php
- ./tests/Drupal/FunctionalJavascriptTests
- ./modules/*/tests/src/FunctionalJavascript
- ../modules/*/tests/src/FunctionalJavascript
- ../profiles/*/tests/src/FunctionalJavascript
- ../sites/*/modules/*/tests/src/FunctionalJavascript
-
- ./vendor
-
- ./drush/tests
+ ./tests/TestSuites/FunctionalJavascriptTestSuite.php
diff --git a/core/tests/Drupal/Tests/Core/Render/RendererTestBase.php b/core/tests/Drupal/Tests/Core/Render/RendererTestBase.php
index 834d0a4..7c5e855 100644
--- a/core/tests/Drupal/Tests/Core/Render/RendererTestBase.php
+++ b/core/tests/Drupal/Tests/Core/Render/RendererTestBase.php
@@ -22,7 +22,7 @@
/**
* Base class for the actual unit tests testing \Drupal\Core\Render\Renderer.
*/
-class RendererTestBase extends UnitTestCase {
+abstract class RendererTestBase extends UnitTestCase {
/**
* The tested renderer.
diff --git a/core/tests/Drupal/Tests/TestSuites/TestSuiteBaseTest.php b/core/tests/Drupal/Tests/TestSuites/TestSuiteBaseTest.php
new file mode 100644
index 0000000..dd0a9be
--- /dev/null
+++ b/core/tests/Drupal/Tests/TestSuites/TestSuiteBaseTest.php
@@ -0,0 +1,135 @@
+ [
+ 'modules' => [],
+ 'profiles' => [],
+ 'tests' => [
+ 'Drupal' => [
+ 'NotUnitTests' => [
+ 'CoreNotUnitTest.php' => ' [
+ 'CoreUnitTest.php' => 'getFilesystem();
+ return [
+ 'unit-tests' => [
+ $filesystem,
+ 'Unit',
+ [
+ 'Drupal\Tests\CoreUnitTest' => 'vfs://root/core/tests/Drupal/Tests/CoreUnitTest.php',
+ ],
+ ],
+ 'not-unit-tests' => [
+ $filesystem,
+ 'NotUnit',
+ [
+ 'Drupal\NotUnitTests\CoreNotUnitTest' => 'vfs://root/core/tests/Drupal/NotUnitTests/CoreNotUnitTest.php',
+ ],
+ ],
+ ];
+ }
+
+ /**
+ * Tests for special case behavior of unit test suite namespaces in core.
+ *
+ * @covers ::addTestsBySuiteNamespace
+ *
+ * @dataProvider provideCoreTests
+ */
+ public function testAddTestsBySuiteNamespaceCore($filesystem, $suite_namespace, $expected_tests) {
+ // Set up the file system.
+ $vfs = vfsStream::setup('root');
+ vfsStream::create($filesystem, $vfs);
+
+ // Make a stub suite base to test.
+ $stub = new StubTestSuiteBase('test_me');
+
+ // Access addTestsBySuiteNamespace().
+ $ref_add_tests = new \ReflectionMethod($stub, 'addTestsBySuiteNamespace');
+ $ref_add_tests->setAccessible(TRUE);
+
+ // Invoke addTestsBySuiteNamespace().
+ $ref_add_tests->invokeArgs($stub, [vfsStream::url('root'), $suite_namespace]);
+
+ // Determine if we loaded the expected test files.
+ $this->assertNotEmpty($stub->testFiles);
+ $this->assertEmpty(array_diff_assoc($expected_tests, $stub->testFiles));
+ }
+
+}
+
+/**
+ * Stub subclass of TestSuiteBase.
+ *
+ * We use this class to alter the behavior of TestSuiteBase so it can be
+ * testable.
+ */
+class StubTestSuiteBase extends TestSuiteBase {
+
+ /**
+ * Test files discovered by addTestsBySuiteNamespace().
+ *
+ * @var string[]
+ */
+ public $testFiles = [];
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function findExtensionDirectories($root) {
+ // We have to stub findExtensionDirectories() because we can't inject a
+ // vfsStream filesystem into drupal_phpunit_find_extension_directories(),
+ // which uses \SplFileInfo->getRealPath(). getRealPath() resolves
+ // stream-based paths to an empty string. See
+ // https://github.com/mikey179/vfsStream/wiki/Known-Issues
+ return [];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function addTestFiles($filenames) {
+ // We stub addTestFiles() because the parent implementation can't deal with
+ // vfsStream-based filesystems due to an error in
+ // stream_resolve_include_path(). See
+ // https://github.com/mikey179/vfsStream/issues/5 Here we just store the
+ // test file being added in $this->testFiles.
+ $this->testFiles = array_merge($this->testFiles, $filenames);
+ }
+
+}
diff --git a/core/tests/TestSuites/FunctionalJavascriptTestSuite.php b/core/tests/TestSuites/FunctionalJavascriptTestSuite.php
new file mode 100644
index 0000000..626be02
--- /dev/null
+++ b/core/tests/TestSuites/FunctionalJavascriptTestSuite.php
@@ -0,0 +1,27 @@
+addTestsBySuiteNamespace($root, 'FunctionalJavascript');
+
+ return $suite;
+ }
+
+}
diff --git a/core/tests/TestSuites/FunctionalTestSuite.php b/core/tests/TestSuites/FunctionalTestSuite.php
new file mode 100644
index 0000000..221a20d
--- /dev/null
+++ b/core/tests/TestSuites/FunctionalTestSuite.php
@@ -0,0 +1,27 @@
+addTestsBySuiteNamespace($root, 'Functional');
+
+ return $suite;
+ }
+
+}
diff --git a/core/tests/TestSuites/KernelTestSuite.php b/core/tests/TestSuites/KernelTestSuite.php
new file mode 100644
index 0000000..2625e2b
--- /dev/null
+++ b/core/tests/TestSuites/KernelTestSuite.php
@@ -0,0 +1,27 @@
+addTestsBySuiteNamespace($root, 'Kernel');
+
+ return $suite;
+ }
+
+}
diff --git a/core/tests/TestSuites/TestSuiteBase.php b/core/tests/TestSuites/TestSuiteBase.php
new file mode 100644
index 0000000..bd047e8
--- /dev/null
+++ b/core/tests/TestSuites/TestSuiteBase.php
@@ -0,0 +1,60 @@
+addTestFiles(TestDiscovery::scanDirectory("Drupal\\Tests\\", "$root/core/tests/Drupal/Tests"));
+ }
+ else {
+ $this->addTestFiles(TestDiscovery::scanDirectory("Drupal\\${suite_namespace}Tests\\", "$root/core/tests/Drupal/${suite_namespace}Tests"));
+ }
+
+ // Extensions' tests will always be in the namespace
+ // Drupal\Tests\$extension_name\$suite_namespace\ and be in the
+ // $extension_path/tests/src/$suite_namespace directory. Not all extensions
+ // will have all kinds of tests.
+ foreach ($this->findExtensionDirectories($root) as $extension_name => $dir) {
+ $test_path = "$dir/tests/src/$suite_namespace";
+ if (is_dir($test_path)) {
+ $this->addTestFiles(TestDiscovery::scanDirectory("Drupal\\Tests\\$extension_name\\$suite_namespace\\", $test_path));
+ }
+ }
+ }
+
+}
diff --git a/core/tests/TestSuites/UnitTestSuite.php b/core/tests/TestSuites/UnitTestSuite.php
new file mode 100644
index 0000000..b05d455
--- /dev/null
+++ b/core/tests/TestSuites/UnitTestSuite.php
@@ -0,0 +1,27 @@
+addTestsBySuiteNamespace($root, 'Unit');
+
+ return $suite;
+ }
+
+}
diff --git a/core/tests/bootstrap.php b/core/tests/bootstrap.php
index 49e350a..804aedf 100644
--- a/core/tests/bootstrap.php
+++ b/core/tests/bootstrap.php
@@ -23,7 +23,9 @@ function drupal_phpunit_find_extension_directories($scan_directory) {
$dirs = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($scan_directory, \RecursiveDirectoryIterator::FOLLOW_SYMLINKS));
foreach ($dirs as $dir) {
if (strpos($dir->getPathname(), '.info.yml') !== FALSE) {
- // Cut off ".info.yml" from the filename for use as the extension name.
+ // Cut off ".info.yml" from the filename for use as the extension name. We
+ // use getRealPath() so that we can scan extensions represented by
+ // directory aliases.
$extensions[substr($dir->getFilename(), 0, -9)] = $dir->getPathInfo()
->getRealPath();
}
@@ -34,11 +36,16 @@ function drupal_phpunit_find_extension_directories($scan_directory) {
/**
* Returns directories under which contributed extensions may exist.
*
+ * @param string $root
+ * (optional) Path to the root of the Drupal installation.
+ *
* @return array
* An array of directories under which contributed extensions may exist.
*/
-function drupal_phpunit_contrib_extension_directory_roots() {
- $root = dirname(dirname(__DIR__));
+function drupal_phpunit_contrib_extension_directory_roots($root = NULL) {
+ if ($root === NULL) {
+ $root = dirname(dirname(__DIR__));
+ }
$paths = array(
$root . '/core/modules',
$root . '/core/profiles',