diff --git a/core/modules/simpletest/src/Tests/SkipRequiredModulesTest.php b/core/modules/simpletest/src/Tests/SkipRequiredModulesTest.php new file mode 100644 index 0000000000..15469433df --- /dev/null +++ b/core/modules/simpletest/src/Tests/SkipRequiredModulesTest.php @@ -0,0 +1,28 @@ +fail('This test should have been skipped during discovery.'); + } + +} diff --git a/core/modules/simpletest/tests/src/Unit/TestInfoParsingTest.php b/core/modules/simpletest/tests/src/Unit/TestInfoParsingTest.php index df98377d15..abdeabe7ff 100644 --- a/core/modules/simpletest/tests/src/Unit/TestInfoParsingTest.php +++ b/core/modules/simpletest/tests/src/Unit/TestInfoParsingTest.php @@ -62,7 +62,7 @@ public function infoParserProvider() { [ 'name' => 'Drupal\FunctionalTests\BrowserTestBaseTest', 'group' => 'browsertestbase', - 'description' => 'Tests BrowserTestBase functionality.', + 'description' => 'Tests \Drupal\Tests\BrowserTestBase.', 'type' => 'PHPUnit-Functional', ], // Classname. diff --git a/core/tests/Drupal/FunctionalTests/BrowserTestBaseTest.php b/core/tests/Drupal/FunctionalTests/BrowserTestBaseTest.php index b555fb66fc..e3785a6ee6 100644 --- a/core/tests/Drupal/FunctionalTests/BrowserTestBaseTest.php +++ b/core/tests/Drupal/FunctionalTests/BrowserTestBaseTest.php @@ -10,6 +10,7 @@ /** * Tests BrowserTestBase functionality. * + * @coversDefaultClass \Drupal\Tests\BrowserTestBase * @group browsertestbase */ class BrowserTestBaseTest extends BrowserTestBase { @@ -185,4 +186,48 @@ public function testInstall() { $this->assertTrue(file_exists($htaccess_filename), "$htaccess_filename exists"); } + /** + * Tests that a test method is skipped when it requires a module not present. + * + * In order to catch checkRequirements() regressions, we have to make a new + * test object and run checkRequirements() here. + * + * @covers ::checkRequirements + * @covers ::checkModuleRequirements + */ + public function testMethodRequiresModule() { + require __DIR__ . '/../../fixtures/BrowserMissingDependentModuleMethodTest.php'; + + $test = new BrowserMissingDependentModuleMethodTest(); + // We have to setName() to the method name we're concerned with. + $test->setName('testRequiresModule'); + $this->setExpectedException( + \PHPUnit_Framework_SkippedTestError::class, + 'Module drupal_dne_module is required.' + ); + $test->checkRequirements(); + } + + /** + * Tests that a test case is skipped when it requires a module not present. + * + * In order to catch checkRequirements() regressions, we have to make a new + * test object and run checkRequirements() here. + * + * @covers ::checkRequirements + * @covers ::checkModuleRequirements + */ + public function testRequiresModule() { + require __DIR__ . '/../../fixtures/BrowserMissingDependentModuleTest.php'; + + $test = new BrowserMissingDependentModuleTest(); + // We have to setName() to the method name we're concerned with. + $test->setName('testRequiresModule'); + $this->setExpectedException( + \PHPUnit_Framework_SkippedTestError::class, + 'Module drupal_dne_module is required.' + ); + $test->checkRequirements(); + } + } diff --git a/core/tests/Drupal/KernelTests/KernelTestBase.php b/core/tests/Drupal/KernelTests/KernelTestBase.php index 45f70fb18b..22e35575f0 100644 --- a/core/tests/Drupal/KernelTests/KernelTestBase.php +++ b/core/tests/Drupal/KernelTests/KernelTestBase.php @@ -21,6 +21,7 @@ use Drupal\simpletest\AssertHelperTrait; use Drupal\Tests\ConfigTestTrait; use Drupal\Tests\RandomGeneratorTrait; +use Drupal\Tests\TestRequirementsTrait; use Drupal\simpletest\TestServiceProvider; use Symfony\Component\DependencyInjection\Reference; use Symfony\Component\HttpFoundation\Request; @@ -53,6 +54,7 @@ use AssertHelperTrait; use RandomGeneratorTrait; use ConfigTestTrait; + use TestRequirementsTrait; /** * {@inheritdoc} @@ -212,60 +214,6 @@ public static function setUpBeforeClass() { } /** - * Returns the drupal root directory. - * - * @return string - */ - protected static function getDrupalRoot() { - return dirname(dirname(substr(__DIR__, 0, -strlen(__NAMESPACE__)))); - } - - /** - * {@inheritdoc} - */ - protected function checkRequirements() { - parent::checkRequirements(); - - $this->root = static::getDrupalRoot(); - - // Check if required dependencies exist. - $annotations = $this->getAnnotations(); - if (!empty($annotations['class']['requires'])) { - $this->checkModuleRequirements($annotations['class']['requires']); - } - if (!empty($annotations['method']['requires'])) { - $this->checkModuleRequirements($annotations['method']['requires']); - } - } - - /** - * Checks missing module requirements. - * - * Iterates through a list of requires annotations and looks for missing - * modules. The test will be skipped if any of the required modules is - * missing. - * - * @param string[] $annotations - * A list of requires annotations from either a method or class annotation. - */ - protected function checkModuleRequirements(array $annotations) { - static::initFileCache(); - // drupal_valid_ua() might not be loaded. - require_once $this->root . '/core/includes/bootstrap.inc'; - foreach ($annotations as $requirement) { - if (strpos($requirement, 'module ') === 0) { - $module = trim(str_replace('module ', '', $requirement)); - try { - $this->getExtensionsForModules([$module]); - } - catch (\PHPUnit_Framework_Exception $e) { - throw new \PHPUnit_Framework_SkippedTestError("Module $module is required."); - } - } - } - } - - /** * {@inheritdoc} */ protected function setUp() { diff --git a/core/tests/Drupal/KernelTests/KernelTestBaseTest.php b/core/tests/Drupal/KernelTests/KernelTestBaseTest.php index 165a27c7be..6c7fe8adab 100644 --- a/core/tests/Drupal/KernelTests/KernelTestBaseTest.php +++ b/core/tests/Drupal/KernelTests/KernelTestBaseTest.php @@ -215,16 +215,15 @@ public function testRenderWithTheme() { * @covers ::checkModuleRequirements */ public function testMethodRequiresModule() { + require __DIR__ . '/../../fixtures/KernelMissingDependentModuleMethodTest.php'; + + $test = new KernelMissingDependentModuleMethodTest(); + // We have to setName() to the method name we're concerned with. + $test->setName('testRequiresModule'); $this->setExpectedException( \PHPUnit_Framework_SkippedTestError::class, 'Module drupal_dne_module is required.' ); - - require __DIR__ . '/../../fixtures/MissingDependentModuleMethodTest.php'; - - $test = new MissingDependentModuleMethodTest(); - // We have to setName() to the method name we're concerned with. - $test->setName('testRequiresModule'); $test->checkRequirements(); } @@ -238,16 +237,15 @@ public function testMethodRequiresModule() { * @covers ::checkModuleRequirements */ public function testRequiresModule() { + require __DIR__ . '/../../fixtures/KernelMissingDependentModuleTest.php'; + + $test = new KernelMissingDependentModuleTest(); + // We have to setName() to the method name we're concerned with. + $test->setName('testRequiresModule'); $this->setExpectedException( \PHPUnit_Framework_SkippedTestError::class, 'Module drupal_dne_module is required.' ); - - require __DIR__ . '/../../fixtures/MissingDependentModuleTest.php'; - - $test = new MissingDependentModuleTest(); - // We have to setName() to the method name we're concerned with. - $test->setName('testRequiresModule'); $test->checkRequirements(); } diff --git a/core/tests/Drupal/Tests/BrowserTestBase.php b/core/tests/Drupal/Tests/BrowserTestBase.php index 754f9d9838..97bb9569cd 100644 --- a/core/tests/Drupal/Tests/BrowserTestBase.php +++ b/core/tests/Drupal/Tests/BrowserTestBase.php @@ -27,6 +27,7 @@ use Drupal\simpletest\BlockCreationTrait; use Drupal\simpletest\NodeCreationTrait; use Drupal\simpletest\UserCreationTrait; +use Drupal\Tests\TestRequirementsTrait; use Symfony\Component\CssSelector\CssSelectorConverter; use Symfony\Component\HttpFoundation\Request; use Psr\Http\Message\RequestInterface; @@ -60,6 +61,7 @@ createContentType as drupalCreateContentType; } use ConfigTestTrait; + use TestRequirementsTrait; use UserCreationTrait { createRole as drupalCreateRole; createUser as drupalCreateUser; diff --git a/core/tests/Drupal/Tests/TestRequirementsTrait.php b/core/tests/Drupal/Tests/TestRequirementsTrait.php new file mode 100644 index 0000000000..7e7575497f --- /dev/null +++ b/core/tests/Drupal/Tests/TestRequirementsTrait.php @@ -0,0 +1,78 @@ +getAnnotations(); + if (!empty($annotations['class']['requires'])) { + $this->checkModuleRequirements($root, $annotations['class']['requires']); + } + if (!empty($annotations['method']['requires'])) { + $this->checkModuleRequirements($root, $annotations['method']['requires']); + } + } + + /** + * Checks missing module requirements. + * + * Iterates through a list of requires annotations and looks for missing + * modules. The test will be skipped if any of the required modules is + * missing. + * + * @param string $root + * The path to the root of the Drupal installation to scan. + * @param string[] $annotations + * A list of requires annotations from either a method or class annotation. + * + * @throws \PHPUnit_Framework_SkippedTestError + * Thrown when the requirements are not met, and this test should be + * skipped. Callers should not catch this exception. + */ + private function checkModuleRequirements($root, array $annotations) { + // drupal_valid_ua() might not be loaded. + require_once $root . '/core/includes/bootstrap.inc'; + // Scan for modules. + $discovery = new ExtensionDiscovery($root, FALSE); + $discovery->setProfileDirectories([]); + $list = $discovery->scan('module'); + // Find requirements in the list of modules. + foreach ($annotations as $requirement) { + if (strpos($requirement, 'module ') === 0) { + $module = trim(str_replace('module ', '', $requirement)); + if (!isset($list[$module])) { + throw new \PHPUnit_Framework_SkippedTestError("Module $module is required."); + } + } + } + } + +} diff --git a/core/tests/fixtures/MissingDependentModuleMethodTest.php b/core/tests/fixtures/BrowserMissingDependentModuleMethodTest.php similarity index 78% copy from core/tests/fixtures/MissingDependentModuleMethodTest.php copy to core/tests/fixtures/BrowserMissingDependentModuleMethodTest.php index a3f62da08a..5ce348baf3 100644 --- a/core/tests/fixtures/MissingDependentModuleMethodTest.php +++ b/core/tests/fixtures/BrowserMissingDependentModuleMethodTest.php @@ -1,8 +1,8 @@