You are here

public function TestBase::run in SimpleTest 8.3

Run all tests in this class.

Regardless of whether $methods are passed or not, only method names starting with "test" are executed.

Parameters

$methods: (optional) A list of method names in the test case class to run; e.g., array('testFoo', 'testBar'). By default, all methods of the class are taken into account, but it can be useful to only run a few selected test methods during debugging.

1 call to TestBase::run()
KernelTestBaseTest::run in src/Tests/KernelTestBaseTest.php
Run all tests in this class.
2 methods override TestBase::run()
InnocuousTest::run in tests/src/Kernel/TestDeprecatedTestHooks.php
Override run() since it uses TestBase.
KernelTestBaseTest::run in src/Tests/KernelTestBaseTest.php
Run all tests in this class.

File

src/TestBase.php, line 889

Class

TestBase
Base class for Drupal tests.

Namespace

Drupal\simpletest

Code

public function run(array $methods = []) {
  $this
    ->checkTestHierarchyMismatch();
  $class = get_class($this);
  if ($missing_requirements = $this
    ->checkRequirements()) {
    $object_info = new \ReflectionObject($this);
    $caller = [
      'file' => $object_info
        ->getFileName(),
    ];
    foreach ($missing_requirements as $missing_requirement) {
      TestBase::insertAssert($this->testId, $class, FALSE, $missing_requirement, 'Requirements check', $caller);
    }
    return;
  }
  TestServiceProvider::$currentTest = $this;
  $simpletest_config = $this
    ->config('simpletest.settings');

  // Unless preset from run-tests.sh, retrieve the current verbose setting.
  if (!isset($this->verbose)) {
    $this->verbose = $simpletest_config
      ->get('verbose');
  }
  if ($this->verbose) {

    // Initialize verbose debugging.
    $this->verbose = TRUE;
    $this->verboseDirectory = PublicStream::basePath() . '/simpletest/verbose';
    $this->verboseDirectoryUrl = file_create_url($this->verboseDirectory);
    if (\Drupal::service('file_system')
      ->prepareDirectory($this->verboseDirectory, FileSystemInterface::CREATE_DIRECTORY) && !file_exists($this->verboseDirectory . '/.htaccess')) {
      file_put_contents($this->verboseDirectory . '/.htaccess', "<IfModule mod_expires.c>\nExpiresActive Off\n</IfModule>\n");
    }
    $this->verboseClassName = str_replace("\\", "_", $class);
  }

  // HTTP auth settings (<username>:<password>) for the simpletest browser
  // when sending requests to the test site.
  $this->httpAuthMethod = (int) $simpletest_config
    ->get('httpauth.method');
  $username = $simpletest_config
    ->get('httpauth.username');
  $password = $simpletest_config
    ->get('httpauth.password');
  if (!empty($username) && !empty($password)) {
    $this->httpAuthCredentials = $username . ':' . $password;
  }

  // Force assertion failures to be thrown as exceptions.
  Handle::register();
  set_error_handler([
    $this,
    'errorHandler',
  ]);

  // 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) {
    return strpos($method, 'test') === 0;
  });
  if (empty($test_methods)) {

    // Call $this->assert() here because we need to pass along custom caller
    // information, lest the wrong originating code file/line be identified.
    $this
      ->assert(FALSE, 'No test methods found.', 'Requirements', [
      'function' => __METHOD__ . '()',
      'file' => __FILE__,
      'line' => __LINE__,
    ]);
  }
  if ($methods) {
    $test_methods = array_intersect($test_methods, $methods);
  }
  foreach ($test_methods as $method) {

    // Insert a fail record. This will be deleted on completion to ensure
    // that testing completed.
    $method_info = new \ReflectionMethod($class, $method);
    $caller = [
      'file' => $method_info
        ->getFileName(),
      'line' => $method_info
        ->getStartLine(),
      'function' => $class . '->' . $method . '()',
    ];
    $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;
    }
    try {
      $this
        ->setUp();
    } 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();
      break;
    }
    try {
      $this
        ->{$method}();
    } catch (\Exception $e) {
      $this
        ->exceptionHandler($e);
    }
    try {
      $this
        ->tearDown();
    } catch (\Exception $e) {
      $this
        ->exceptionHandler($e);

      // If a test fails to tear down, abort the entire test class, since
      // 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();
      break;
    }
    $this
      ->restoreEnvironment();

    // Remove the test method completion check record.
    TestBase::deleteAssert($test_completion_check_id);
  }
  TestServiceProvider::$currentTest = NULL;

  // Clear out the error messages and restore error handler.
  \Drupal::messenger()
    ->deleteAll();
  restore_error_handler();
}