diff --git a/core/modules/path/lib/Drupal/path/Tests/PathAliasTest.php b/core/modules/path/lib/Drupal/path/Tests/PathAliasTest.php index e97101d..b55086b 100644 --- a/core/modules/path/lib/Drupal/path/Tests/PathAliasTest.php +++ b/core/modules/path/lib/Drupal/path/Tests/PathAliasTest.php @@ -7,17 +7,12 @@ namespace Drupal\path\Tests; +use Drupal\simpletest\SingleEnvInterface; + /** * Tests path alias functionality. */ -class PathAliasTest extends PathTestBase { - - /** - * Modules to enable. - * - * @var array - */ - public static $modules = array('path'); +class PathAliasTest extends PathTestBase implements SingleEnvInterface { public static function getInfo() { return array( @@ -27,8 +22,8 @@ public static function getInfo() { ); } - function setUp() { - parent::setUp(); + function setUpBeforeClass() { + parent::setUpBeforeClass(); // Create test user and login. $web_user = $this->drupalCreateUser(array('create page content', 'edit own page content', 'administer url aliases', 'create url aliases')); diff --git a/core/modules/path/lib/Drupal/path/Tests/PathTestBase.php b/core/modules/path/lib/Drupal/path/Tests/PathTestBase.php index 97f3f81..b4e71d6 100644 --- a/core/modules/path/lib/Drupal/path/Tests/PathTestBase.php +++ b/core/modules/path/lib/Drupal/path/Tests/PathTestBase.php @@ -8,6 +8,7 @@ namespace Drupal\path\Tests; use Drupal\simpletest\WebTestBase; +use Drupal\simpletest\SingleEnvInterface; /** * Provides a base class for testing the Path module. @@ -21,9 +22,21 @@ */ public static $modules = array('node', 'path'); + function setUpBeforeClass() { + parent::setUpBeforeClass(); + if ($this instanceof SingleEnvInterface) { + $this->doSetUp(); + } + } + function setUp() { parent::setUp(); + if (!$this instanceof SingleEnvInterface) { + $this->doSetUp(); + } + } + private function doSetUp() { // Create Basic page and Article node types. if ($this->profile != 'standard') { $this->drupalCreateContentType(array('type' => 'page', 'name' => 'Basic page')); diff --git a/core/modules/simpletest/lib/Drupal/simpletest/SingleEnvInterface.php b/core/modules/simpletest/lib/Drupal/simpletest/SingleEnvInterface.php new file mode 100644 index 0000000..d1ccf9a --- /dev/null +++ b/core/modules/simpletest/lib/Drupal/simpletest/SingleEnvInterface.php @@ -0,0 +1,25 @@ +class === $parent_class) { + continue; + } + $compatible = FALSE; + $this->fail("$parent_class does not support SingleEnvInterface.", 'Requirements check'); + } + if (!$compatible) { + return; + } + + // Insert a fail record. This will be deleted on completion to ensure + // that testing completed. + $class_info = new \ReflectionClass($class); + $caller = array( + 'file' => $class_info->getFileName(), + 'line' => $class_info->getStartLine(), + 'function' => $class, + ); + $class_completion_check_id = TestBase::insertAssert($this->testId, $class, FALSE, 'The test class did not complete due to a fatal error.', 'Completion check', $caller); + + try { + $this->prepareEnvironment(); + } + catch (\Exception $e) { + $this->exceptionHandler($e); + // The prepareEnvironment() method isolates the test from the parent + // Drupal site by creating a random database prefix and test site + // directory. If this fails, a test would possibly operate in the + // parent site. Therefore, the entire test run for this test class + // has to be aborted. + // restoreEnvironment() cannot be called, because we do not know + // where exactly the environment setup failed. + return; + } + try { + $this->setUpBeforeClass(); + } + catch (\Exception $e) { + $this->exceptionHandler($e); + // Abort if setUp() fails, since all test methods will fail. + // But ensure to clean up and restore the environment, since + // prepareEnvironment() succeeded. + $this->restoreEnvironment(); + return; + } + } + // Iterate through all the methods in this class, unless a specific list of // methods to run was passed. $test_methods = array_filter(get_class_methods($class), function ($method) { @@ -823,19 +889,21 @@ public function run(array $methods = array()) { ); $test_completion_check_id = TestBase::insertAssert($this->testId, $class, FALSE, 'The test did not complete due to a fatal error.', 'Completion check', $caller); - try { - $this->prepareEnvironment(); - } - catch (\Exception $e) { - $this->exceptionHandler($e); - // The prepareEnvironment() method isolates the test from the parent - // Drupal site by creating a random database prefix and test site - // directory. If this fails, a test would possibly operate in the - // parent site. Therefore, the entire test run for this test class - // has to be aborted. - // restoreEnvironment() cannot be called, because we do not know - // where exactly the environment setup failed. - break; + if (!$setup_once) { + try { + $this->prepareEnvironment(); + } + catch (\Exception $e) { + $this->exceptionHandler($e); + // The prepareEnvironment() method isolates the test from the parent + // Drupal site by creating a random database prefix and test site + // directory. If this fails, a test would possibly operate in the + // parent site. Therefore, the entire test run for this test class + // has to be aborted. + // restoreEnvironment() cannot be called, because we do not know + // where exactly the environment setup failed. + break; + } } try { @@ -846,7 +914,9 @@ public function run(array $methods = array()) { // Abort if setUp() fails, since all test methods will fail. // But ensure to clean up and restore the environment, since // prepareEnvironment() succeeded. - $this->restoreEnvironment(); + if (!$setup_once) { + $this->restoreEnvironment(); + } break; } try { @@ -864,15 +934,32 @@ public function run(array $methods = array()) { // it is likely that all tests will fail in the same way and a // failure here only results in additional test artifacts that have // to be manually deleted. - $this->restoreEnvironment(); + if (!$setup_once) { + $this->restoreEnvironment(); + } break; } - $this->restoreEnvironment(); + if (!$setup_once) { + $this->restoreEnvironment(); + } // Remove the test method completion check record. TestBase::deleteAssert($test_completion_check_id); } + if ($setup_once) { + try { + $this->tearDownAfterClass(); + } + catch (\Exception $e) { + $this->exceptionHandler($e); + } + $this->restoreEnvironment(); + + // Remove the test class completion check record. + TestBase::deleteAssert($class_completion_check_id); + } + TestServiceProvider::$currentTest = NULL; // Clear out the error messages and restore error handler. drupal_get_messages(); diff --git a/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php b/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php index 942ebab..c308685 100644 --- a/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php +++ b/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php @@ -729,6 +729,18 @@ protected function drupalLogout() { } } + public function setUpBeforeClass() { + if ($this instanceof SingleEnvInterface) { + $this->doSetUp(); + } + } + + protected function setUp() { + if (!$this instanceof SingleEnvInterface) { + $this->doSetUp(); + } + } + /** * Sets up a Drupal site for running functional and integration tests. * @@ -744,7 +756,7 @@ protected function drupalLogout() { * default values may be incompatible with the environment in which tests are * being executed. */ - protected function setUp() { + private function doSetUp() { // When running tests through the Simpletest UI (vs. on the command line), // Simpletest's batch conflicts with the installer's batch. Batch API does // not support the concept of nested batches (in which the nested is not @@ -1058,18 +1070,30 @@ protected function refreshVariables() { $this->container->get('state')->resetCache(); } + public function tearDownAfterClass() { + if ($this instanceof SingleEnvInterface) { + $this->doTearDown(); + } + } + + protected function tearDown() { + if (!$this instanceof SingleEnvInterface) { + $this->doTearDown(); + } + parent::tearDown(); + } + /** * Cleans up after testing. * * Deletes created files and temporary files directory, deletes the tables * created by setUp(), and resets the database prefix. */ - protected function tearDown() { + protected function doTearDown() { // Destroy the testing kernel. if (isset($this->kernel)) { $this->kernel->shutdown(); } - parent::tearDown(); // Ensure that internal logged in variable and cURL options are reset. $this->loggedInUser = FALSE;